面试题29:数组中出现次数超过一半的数字
来源:互联网 发布:怎么做淘宝图片 编辑:程序博客网 时间:2024/03/29 14:46
面试题29:数组中出现次数超过一半的数字
题目描述:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
题目分析:
找出在数组中出现次数超过一半的数。直观的解法是,数组排序,排序后数一下得出出现次数超过一半的数,时间复杂度是O(NlogN),那有没有更好的解法。
1. hash表的解法
思路1:
用哈希表存起来数组的元素,一次遍历,如果hash[num[i]]大于数组的一半时,返回num[i],空间复杂度是O(N),显然是用空间换取时间的解法。
2. 基于partition的O(N)的算法
思路2:
再来分析排序后的数组,出现次数超过一半的数一定在排序后数组的中间,相当于查找数组的中位数,那我们走到这里,正确的思路是:联想到我们有成熟的O(N)的算法求任意数组中第k大的数字(就是快速排序第一次partition的过程),于是我们有了如下解法:
快速排序的partition,选中key值,小于key的在左边,大于等于key的在key右边,partition结束后key落在正确的位置,
- 如果key的下标是中间的位置,则直接返回就是我们想要的结果;
- 如果key的下标小于中间的位置,则在key的右半部分查找;
- 如果key的下标大于中间的位置,则在key的左半部分查找;
代码如下:
class Solution {public: int MoreThanHalfNum_Solution(vector<int> numbers) { int len = numbers.size(); if (len == 0) return 0; int left, right, mid, pos, val; left = 0; right = len - 1; mid = len / 2; pos = Partition(numbers, left, right); while (pos != mid) { if (pos > mid) { right = pos - 1; pos = Partition(numbers, left, right); }else { left = pos + 1; pos = Partition(numbers, left, right); } } val = numbers[pos]; if (CheckHalf(numbers, val)) return val; else return 0; } int Partition(vector<int> &num, int left, int right) { int pivot = num[left]; while (left < right) { while (left < right && num[right] >= pivot) -- right; num[left] = num[right]; while (left < right && num[left] < pivot) ++ left; num[right] = num[left]; } num[left] = pivot; return left; } /* 检查最后的val值是否在数组中出现次数超过一半 */ bool CheckHalf(vector<int> num, int val) { int len = num.size(); int count = 0; for (int i = 0; i < len; i ++) if (num[i] == val) ++ count; if (count > len / 2) return true; else return false; }};
3. 基于数组特点的O(N)的算法
思路3:
考虑到数组的特点,有了如下解法:
我们在遍历数组时,保存两个值一个是val记录当前的值,一个出现次数count。
- 当我们遍历到下一个数字时,如果和val相等,则count+1;否则count-1;
- 当count等于0时,重新记录val的值;
代码如下:
class Solution {public: int MoreThanHalfNum_Solution(vector<int> numbers) { int len = numbers.size(); if (len == 0) return 0; int val, i, count; val = numbers[0]; count = 1; for (i = 1; i < len; i ++) { if (count == 0) val = numbers[i]; if (numbers[i] == val) ++ count; else -- count; } if (CheckHalf(numbers, val)) return val; else return 0; } /* 检查最后的val值是否在数组中出现次数超过一半 */ bool CheckHalf(vector<int> num, int val) { int len = num.size(); int count = 0; for (int i = 0; i < len; i ++) if (num[i] == val) ++ count; if (count > len / 2) return true; else return false; }};
推荐:http://taop.marchtea.com/04.03.html
0 0
- 面试题:数组中出现次数超过一半的数字
- 面试题:数组中出现次数超过一半的数字
- 面试题29:数组中出现次数超过一半的数字
- [剑指offer][面试题29]数组中出现次数超过一半的数字
- 数组中出现次数超过一半的数字(面试题 29)
- 剑指Offer:面试题29 数组中出现次数超过一半的数字
- 面试题29 数组中出现次数超过一半的数字
- 剑指offer 面试题29—数组中出现次数超过一半的数字
- 《剑指Offer》学习笔记--面试题29:数组中出现次数超过一半的数字
- 面试题29:数组中出现次数超过一半的数字
- 面试题29:数组中出现次数超过一半的数字
- 【剑指Offer学习】【面试题29 :数组中出现次数超过一半的数字】
- 面试题29_数组中出现次数超过一半的数字
- 剑指Offer面试题29(java版):数组中出现次数超过一半的数字
- 面试题29数组中出现次数超过一半的数字
- 剑指offer面试题29-数组中出现次数超过一半的数字
- 面试题29:数组中出现次数超过一半的数字
- 面试题29:数组中出现次数超过一半的数字
- 配置jdk比较简单的方法
- 上转型和下转型
- ocp-172
- C#comboBox的使用
- ocp-173
- 面试题29:数组中出现次数超过一半的数字
- C++实现KMP算法(单值返回版)
- 回文数
- 【译】29个你必须知道的Linux命令
- tabview
- ocp-174
- 返回顶部按钮实现
- ocp-175
- 环境光传感器(ALS)背光控制解决方案