算法学习(十一)数组中出现次数超过长度一半的数
2016-05-09 17:42
267 查看
数组中出现次数超过数组长度一半的 数字
题目描述:给定 一个数组,找到数组中出现次数超过数组长度一半的数字,如数组 a[]= {0,1,2,1,1},输出为1
分析:
1,可以使用伴随数组b,遍历数组a,将值作为数组b的下标,将次数作为值,然后遍历数组b,找到次数超过一半的值,然后输出。时间复杂度为O(N),不过要增加空间复杂度。
2,我们可以先对数组进行排序,因为某个数字出现次数超过一半,所以在数组的N/2处,就一定是那个数字。时间复杂主要为排序的时间,使用快排O (N*logN).
3,有个数字出现的次数比其他的所有数组出现次数之和还要多,那么我们可以在遍历数组时,保存两个值,一个为数字,一个为次数,如果下一个数字和保存的数字不同,次数就减一,如果和保存的相同,次数就加一,如果次数为零,就保存下一个数字,且把次数重置为1,直到数组结束,保存的数字就是需要的。利用的就是数字的次数之和比其他的数字次数之和大,不同的就减,最后的次数肯定不为0。
例子: 0,1,2,1,1:
i = 0,result = 0,times = 1;
i = 1,a[1] != result,times–;times= 0;
i = 2,因为times = 0;result = a[2],times 重置为1;
i= 3,a[3] != result;times–;times = 0;
i = 4, result = 1;times = 1;
输出result = 1;
#include <iostream> using namespace std; int Find(int * data,int length) { int result,times; times = 0; int i; for(i = 0;i<length;i++) { if(times == 0) { result = data[i]; times =1; } else { if(result == data[i]) times++; else times--; } } return result; } int main() { int a[5] = {0,1,2,1,1}; cout << Find(a,5) << endl; return 0; }
数组中数字出现次数为长度一半的时候
这个时候,上面的方法就不行了,因为在遍历到最后一个数字时,times = 0,这个时候我们需要最后一个数,但是数组已经遍历完毕,保存可能是前面的某一个数。如0,1,2,1
i = 0 ,result =0,times = 1;
i = 1,a[1]!= result;times–;times = 0;
i = 2 ,result = 2;times = 1;
i = 3,a[3] != result,times–;times = 0;
输出result = 2;但是我们需要时返回2的下一个数1。
如果是0,2,1,1
i = 0;result = 0;times= 1;
i = 1,a[1] != result ;times–;times= 0;
i = 2,result = 1,times = 1;
i = 3,a[3] == result;times++;times = 2;
输出result = 1;
我们会发现,实际上我们要判断的就是遍历到最后的时候保存的result和最后一个元素的比较,最后的输出从两个数之间选出。
我们可以针对最后一个元素,声明一个变量ntimes,遍历数组时,判断如果当前元素等于最后的元素,ntimes次数加一,最后直接判断,ntimes == N/2 ,如果true,说明最后一个元素就是,如果false,说明result中保存的数就是要找的。
int Find2(int * data,int length) { int result,times,ntimes; times = ntimes = 0; int i; for(i = 0;i<length;i++) { if(data[i] == data[length-1]) ntimes++; //最后一个元素出现次数 if(times== 0) { result = data[i]; times = 1; } else { if(data[i] == result) times++; else times--; } } if(ntimes*2 == length) return data[length-1]; else return result; }
相关文章推荐
- android studio 查看 keystore MD5等信息
- libdvm.so has text relocations 错误
- listview最多选几个
- 第五次作业(计算器第三步之文件输入输出)
- Linux中丢失grub文件怎么办?
- length()与lengthb()
- 求因子数的和问题
- Cocos2dx_3.x新的渲染流程
- BaseAdapter 抽取
- springMVC加载远程freemarker模板文件
- HTML DOCTYPE文档类型举例说明
- 在iis中设置文件下载而不是在浏览器上打开
- 去除android手机滚动条
- android notification完全解析【转】
- 集合框架--Map集合之LinkedHashMap
- 在配置文件(manifest file)中声明activity的一点理解
- c++中反斜杠(\)的不常用的用法
- 【转】NodeJS on Nginx: 使用nginx反向代理处理静态页面
- Android-GestureDetector手势滑动
- hive union 的问题