【问题】
题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。
【分析】
解法1:
先排序,排序后数组中间的那个元素就是要找的那个数字。时间复杂度O(n*logn)。
解法2:
既要缩小总的时间复杂度,那么可以用查找时间复杂度为O(1)的hash表,即以空间换时间。哈希表的键值(Key)为数组中的数字,值(Value)为该数字对应的次数。然后直接遍历整个hash表,找出每一个数字在对应的位置处出现的次数,输出那个出现次数超过一半的数字即可。
解法3:
咱们根据数组的特性考虑到:
【代码】
#include <stdio.h> #include <stdlib.h> int FindNumber1(int *a, int len)//解法3 { int i; int candidate = a[0]; int nTime = 1; for (i = 0; i < len; i++) { if (candidate == a[i]) nTime++; else nTime--; if (nTime == 0) { candidate = a[i]; nTime = 1; } } return candidate; } void q_sort(int *a, int start, int end) { int tmp = a[start]; int i = start, j = end; if (start + 1 > end) return; while (i < j) { while (i < j && a[j] > tmp) j--; if (i < j) a[i++] = a[j]; while (i < j && a[i] < tmp) i++; if (i < j) a[j--] = a[i]; } a[i] = tmp; q_sort(a, start, i - 1); q_sort(a, i + 1, end); } int FindNumber2(int *a, int len)//解法1 { q_sort(a, 0, len-1); return a[(len / 2)]; } int main(void) { int a[] = {0, 1, 1, 2, 1, 2, 2, 2, 2}; int len = sizeof(a) / sizeof(int); int res; res = FindNumber1(a, len); printf("%d\n", res); res = FindNumber2(a, len); printf("%d\n", res); return 0; }
原文地址:http://blog.csdn.net/jjjcainiao/article/details/38761445