数组中出现次数超过一半的数字
2016-06-23 10:01
183 查看
题目:数组中有一个数字出现超过数组长度的一半,请找出这个数字。列入输入一个长度为9的数组{1,2,3,2,2,2,5,4,2},由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。 看到题目的第一感觉就是要先把未排序的数组排序,排序的最小时间复杂度(快速排序) O(N*logN) , 加上遍历,时间复杂度为: O(N*logN+N) 第二种方法是考虑每次删除两个不同的数,那么在剩下的数中,出现的次数仍然超过总数的一半。通过不断重复这个过程,不断排除掉其它的数,最终找到那个出现次数超过一半的数字。这个方法,免去了上述思路一、二的排序,也避免了思路三空间O(N)的开销,总得说来,时间复杂度只有O(N),空间复杂度为O(1),不失为最佳方法。 还有就是可以利用哈希表。如果所选的数组的元素比较集中的话可以使用哈希表统计每个元素出现的次数,时间复杂度是O(N),但是题目并没有给出数组元素的范围。次方法也不太好。有了上面的思路后,我们不难写出这样实现代码: 方法一:使用快排的思想实现
方法二:遍历数组时保存两个值,一个是数组中的数字,另一个是次数,当遍历到下一个数字时,如果下一个数字与之前保存的数字相同,则次数加1,如果不同,则次数减1,如果次数为0,则需要保存下一个数字,并把次数设定为1。由于我们要找的数字出现的次数比其他所有数字的出现次数之和还要大,则要找的数字肯定是组后一次把次数设为1时对应的数字。该方法的时间复杂度为O(n),空间复杂度为O(1)。
int Partition(int A[],int low,int high) { int pivot=A[low]; while(low <high) { while(low<high && A[high]>=pivot) --high; A[low]=A[high]; while(low<high && A[low]<=pivot) ++low; A[high]=A[low]; } A[low]=pivot; return low; } int HalfData(int a[],int len) { int start=0; int end=len-1; int middle=len >> 1; int index=Partition(a,start,end); printf("index1:%d\n",index); while(index != middle) { if(index > middle) { end=index-1; index=Partition(a,start,end); } else { start=index+1; index=Partition(a,start,end); } } return a[index]; }
方法二:遍历数组时保存两个值,一个是数组中的数字,另一个是次数,当遍历到下一个数字时,如果下一个数字与之前保存的数字相同,则次数加1,如果不同,则次数减1,如果次数为0,则需要保存下一个数字,并把次数设定为1。由于我们要找的数字出现的次数比其他所有数字的出现次数之和还要大,则要找的数字肯定是组后一次把次数设为1时对应的数字。该方法的时间复杂度为O(n),空间复杂度为O(1)。
int MoreThanHalfNum(int* numbers, unsigned int length) { if(numbers == NULL && length == 0) { g_bInputInvalid = true; return 0; } g_bInputInvalid = false; int result = numbers[0]; int times = 1; for(int i = 1; i < length; ++i) { if(times == 0) { result = numbers[i]; times = 1; } else if(numbers[i] == result) times++; else times--; } times = 0; for(int i = 0; i < length; ++i) { if(numbers[i] == result) times++; } if(times * 2 <= length) { g_bInputInvalid = true; result = 0; } return result; }
相关文章推荐
- gitinspector+jenkins 开发代码统计CI
- 空间两大拓展功能 引爆企业发展需求
- 空间支持多子网站 有效降低建站成本
- 奔月互联免费50m/5g/asp/ftp/可绑米空间
- 三维免费空间提供多款免费ASP空间(1G)
- 空间页面CSS说明
- C#实现统计字数功能的方法
- PowerShell统计文件夹下文件个数的方法
- C#实现将数组内元素打乱顺序的方法
- jQuery删除一个元素后淡出效果展示删除过程的方法
- jQuery拖动元素并对元素进行重新排序
- 如何统计全天各个时间段产品销量情况(sqlserver)
- C#统计字符串中数字个数的方法
- C语言中使用lex统计文本文件字符数
- 如何统计在一篇文章中某个单词出现了几次,以及第一次出现的位置
- SQL进行排序、分组、统计的10个新技巧分享
- Perl中怎样从数组中删除某个值?
- 最省空间的计数器
- PHP的数组中提高元素查找与元素去重的效率的技巧解析
- php实现统计目录文件大小的函数