博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
27 数组中出现次数超过一半的数字
阅读量:5328 次
发布时间:2019-06-14

本文共 5448 字,大约阅读时间需要 18 分钟。

题目描述

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
 
 
思路:第一种方法是抵消的思路,如果一个数字在一个数组中出现的次数超过一半,那么一一抵消之后,最后剩下的一定是目标数字。一定要注意找到元素之后要验证是否该数字超过数组长度的一半。
维护两个变量,一个记数,一个保存数组元素,如果遍历到下一个数字的时候,和保存数字相同,则记数值加1,否则减1。注意这两个变量初始化,记数值开始为1,进入循环后如果变为0了,要重新赋值为1,并且保存值的变量也更新。
class Solution {public:    bool checked(vector
&numbers,int num){
//检测得到的答案是否合法,查过数组数量的一半 int len = 0; for(int i = 0;i < numbers.size();++i){ if(num == numbers[i]){ ++len; } } if(len <= (numbers.size() / 2)){ return false; } return true; } int MoreThanHalfNum_Solution(vector
numbers) { if(numbers.empty()){ return 0; } int cnt = 1;//先初始化为1 int flag = numbers[0]; for(int i = 0;i < numbers.size();++i){ if(cnt == 0){ cnt = 1; flag = numbers[i]; } else if(flag == numbers[i]){ ++cnt; } else{ --cnt; } } if(checked(numbers,flag)){ return flag; } return 0; }};

第二种思路是借鉴快速排序的方法,事实上可以不用对数组进行排序,或者说仅部分排序,受快速排序的partition函数的启发,我们可以利用反复调用partition函数来求的该数字。我们现在数组中随机选取一个数字,而后通过Partition函数返回该数字在数组中的索引index,如果index刚好等于n/2,则这个数字便是数组的中位数,也即是要求的数,如果index大于n/2,则中位数肯定在index的左边,在左边继续寻找即可,反之在右边寻找。这样可以只在index的一边寻找,而不用两边都排序,减少了一半排序时间。这种情况的平均时间复杂度大致为:T(n) = n+n/2+n/4+n/8+....+1,很明显当n很大时,T(n)趋近于2n,也就是说平均情况下时间复杂度为O(n),但是这种情况下,最坏的时间复杂度依然为O(n*n),最坏情况下,index总是位于数组的最左或最右边,这样时间复杂度为T(n) = n+n-1+n-2+n-3+....+1 = n(n-1)/2,显然,时间复杂度为O(n*n),空间复杂度为O(1)。

idx = partition(numbers,lo,hi);位置非常重要,下面这种在下题就有bug,这题没毛病,不过还是应该idx定义的时候写这个。
class Solution {public:    int partition(vector
&numbers,int lo,int hi){ int pos = lo + rand() % (hi - lo + 1); int pivot = numbers[pos]; swap(numbers[lo],numbers[pos]); while(lo < hi){ while(lo < hi){
//从右往左找第一个小于pivot if(numbers[hi] > pivot){ --hi; } else{ numbers[lo] = numbers[hi]; ++lo; break; } } while(lo < hi){
//从左往右找第一个大于pivot if(numbers[lo] < pivot){ ++lo; } else{ numbers[hi] = numbers[lo]; --hi; break; } } } numbers[lo] = pivot; return lo; } bool checked(vector
&numbers,int flag){ int len = 0; for(int i = 0;i < numbers.size();++i){ if(numbers[i] == flag){ ++len; } } if(len <= (numbers.size() / 2)){ return false; } return true; } int MoreThanHalfNum_Solution(vector
numbers) { if(numbers.empty()){ return 0; } int mid = numbers.size() / 2 ; int idx = 0; int lo = 0,hi = numbers.size() - 1; while(idx != mid){ idx = partition(numbers,lo,hi); if(idx < mid){ lo = idx + 1; } if(idx > mid){ hi = idx - 1; } } if(checked(numbers,numbers[idx])){ return numbers[idx]; } return 0; }};

 

 正确版本:

 

 

class Solution {public:    int partition(vector
&numbers,int lo,int hi){ int pos = lo + rand() % (hi - lo + 1); int pivot = numbers[pos]; swap(numbers[lo],numbers[pos]); while(lo < hi){ while(lo < hi){
//从右往左找第一个小于pivot if(numbers[hi] > pivot){ --hi; } else{ numbers[lo] = numbers[hi]; ++lo; break; } } while(lo < hi){
//从左往右找第一个大于pivot if(numbers[lo] < pivot){ ++lo; } else{ numbers[hi] = numbers[lo]; --hi; break; } } } numbers[lo] = pivot; return lo; } bool checked(vector
&numbers,int flag){ int len = 0; for(int i = 0;i < numbers.size();++i){ if(numbers[i] == flag){ ++len; } } if(len <= (numbers.size() / 2)){ return false; } return true; } int MoreThanHalfNum_Solution(vector
numbers) { if(numbers.empty()){ return 0; } int mid = numbers.size() / 2 ; int idx = 0; idx = partition(numbers,lo,hi); int lo = 0,hi = numbers.size() - 1; while(idx != mid){ if(idx < mid){ lo = idx + 1; } if(idx > mid){ hi = idx - 1; } idx = partition(numbers,lo,hi); } if(checked(numbers,numbers[idx])){ return numbers[idx]; } return 0; }};

 

 

转载于:https://www.cnblogs.com/dingxiaoqiang/p/8027808.html

你可能感兴趣的文章
Activiti开发案例之代码生成工作流图片
查看>>
angularJs完成分页
查看>>
【原创】Mapped Statements collection does not contain value for DaoImpl.method
查看>>
docker nginx 反向代理
查看>>
SWUST OJ Coin Changing
查看>>
eclipse重定向输入输出到文件
查看>>
SGDMA
查看>>
20145235李涛《网络对抗》Exp8 Web基础
查看>>
Git-SSH
查看>>
使用JavaMail发送邮件-从FTP读取图片并添加到邮件正文发送
查看>>
HDU4635 Strongly connected
查看>>
visual studio插件开发dll类库免加全局缓存处理办法
查看>>
CodeForces 520C 水构造
查看>>
SVN配置–服务器端(linux)
查看>>
document.body、document.documentElement和window获取视窗大小的差别
查看>>
hdu3535 AreYouBusy
查看>>
SDL2源码分析1:初始化(SDL_Init())
查看>>
SignalR Troubleshooting
查看>>
Windows Phone 7 异步编程模型
查看>>
oracle10g连接自动断开,报ORA-03135错误
查看>>