leetcode-169. Majority Element
来源:互联网 发布:国际象棋和围棋 知乎 编辑:程序博客网 时间:2024/06/06 05:12
leetcode-169. Majority Element
Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.
You may assume that the array is non-empty and the majority element always exist in the array.
题目大意:
给定一个大小为n的数组,找到大多数元素。大多数元素是出现超过⌊n / 2⌋次的元素。 您可能会认为该数组是非空的,而且大多数元素始终存在于数组中。
题目本身还是容易的,主要是记录一下各种解法:
解法一:HashMap
我们可以使用一个HashMap来将元素映射到value上,以便通过在数字上循环来计算线性时间的出现次数。然后,我们只需返回最大值的key。
class Solution { private Map<Integer, Integer> countNums(int[] nums) { Map<Integer, Integer> counts = new HashMap<Integer, Integer>(); for (int num : nums) { if (!counts.containsKey(num)) { counts.put(num, 1); } else { counts.put(num, counts.get(num)+1); } } return counts; } public int majorityElement(int[] nums) { Map<Integer, Integer> counts = countNums(nums); Map.Entry<Integer, Integer> majorityEntry = null; for (Map.Entry<Integer, Integer> entry : counts.entrySet()) { if (majorityEntry == null || entry.getValue() > majorityEntry.getValue()) { majorityEntry = entry; } } return majorityEntry.getKey(); }}
方法二:排序
这个是比较好的方法,将数组排序后,出现超过半数的元素,肯定是length/2
位置的元素
class Solution { public int majorityElement(int[] nums) { Arrays.sort(nums); return nums[nums.length/2]; }}
方法三:随机
这种方法也不是很难理解,但是时间复杂度的证明是比较困难的,也就是为什么没有超时。。
该方法的思路是既然所求的元素在数组中出现的次数超过半数,那么我们随机取数的话,取到的元素也很有可能就是所求的元素。
每次随机取一个数,然后遍历整个数组,计算出现的次数是否超过半数,如果不超过半数就继续取值,直到取到结果为止。
class Solution { private int randRange(Random rand, int min, int max) { return rand.nextInt(max - min) + min; } private int countOccurences(int[] nums, int num) { int count = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] == num) { count++; } } return count; } public int majorityElement(int[] nums) { Random rand = new Random(); int majorityCount = nums.length/2; while (true) { int candidate = nums[randRange(rand, 0, nums.length)]; if (countOccurences(nums, candidate) > majorityCount) { return candidate; } } }}
方法四:分治法
将数组分成两部分,寻找第一个部分中出现次数超过一半的元素为A,第二个部分出现次数超过一半的元素为B,如果A==B,那么A就是这个数组中出现次数超过一半的元素,如果A!=B,那么A和B都可能是这个数组中出现次数超过一半的元素,那么重新遍历这个数组,记录A和B出现的次数,返回出现次数多的元素,时间复杂度T(n)=2T(n/2)+2n=O(nlogn)
。
根据 主定理,循环满足条件2,所以得:
public static void main(String[] args) { int majorityElement(vector<int>& nums) { return helper(nums,0,nums.size()-1); } helper(vector<int> nums,int begin,int end){ if(begin == end) return nums[begin]; else{ int mid = begin + (end-begin)/2; int left = helper(nums,begin,mid); int right = helper(nums,mid+1,end); if(left == right) return left; else{ int leftCount = 0; int rightCount = 0; for (int i = begin;i<=end ;i++ ) { if (nums[i] == left) leftCount++; else if(nums[i] == right) rightCount++; } if (leftCount<rightCount) return right; else return left; } } }}
方法五:Boyer-Moore Voting Algorithm
建议! 读过思路后,阅读一下solution 代码,再回想一下思路 !,就比较容易理解。
这种方法的思路是:每次从数组中找出一对不同的数字,将他们从数组中删除,当最后肯定至少剩下一个元素(3个元素的情况下)(!保证数组中一定存在出现次数超过半数的数字)。
那怎么找到一对不同的数字?怎么删除呢?
在算法的执行过程中,使用一个常量空间来记录候选元素 c
以及他出现的次数 f(c)
, c
即为当前阶段出现超过半次的元素(当前阶段指在遍历数组的过程中的 前i
个元素)。
在开始之前,c
为第一个元素, f(c)
为 0
,然后开始遍历数组:
如果数组A[i] == c
,即元素相同,则f(c)+=1
如果数组A[i] !== c
,即元素不相同,则 f(c)-=1
,即删除这个元素的计数。
如果元素相同或者计数为0,则应该更新元素并将计数加1。
对于两个不同元素,在遍历过后就会使计数器重新变回0,就相当于删除了两个不同元素!
在遍历的过程中,如果 f(c) = 0
,表示当前并没有候选的元素存在;如果f(c)!=0
就是在当前阶段存在候选元素(元素在当前阶段出现超过半数),那么他在剩余的字符串中出现的次数也用超过半数,所以方法是可行的。
int majorityElement(vector<int>& nums) { int count=0; int result=nums[0]; for(int i=0;i<nums.size();i++) { if(count==0||nums[i]==result) { count++; result=nums[i]; } else count--; } return result;}
本来最后f(c) > 0
的元素可能并不是出现半次以上的元素,比如{1,2,3}
,需要遍历数组确认是否出现超过半次,但是题目保证存在出现半次以上的元素,就不用考虑了。
- [LeetCode]169.Majority Element
- LeetCode 169.Majority Element
- 【LeetCode】169.Majority Element
- LeetCode 169. Majority Element
- LeetCode 169. Majority Element
- [leetcode] 169.Majority Element
- Leetcode 169. Majority Element
- 【LeetCode】169. Majority Element
- [LeetCode]169. Majority Element
- 169. Majority Element LeetCode
- LeetCode 169. Majority Element
- LeetCode 169. Majority Element
- Leetcode 169. Majority Element
- [LeetCode]169. Majority Element
- 【LeetCode】169. Majority Element
- leetcode 169. Majority Element
- leetcode 169. Majority Element
- [leetcode] 169. Majority Element
- ASP.NET MVC
- golang使用yaml格式解析构建配置文件
- 说说依赖包的管理和维护
- 六周一次课(11月20日) 12.1 安装客户端 12.2 数据库连接 12.3 mysql事务 12.4 mysql操作数据
- 微信公众号开发用到的一些工具
- leetcode-169. Majority Element
- 1042 电子老鼠闯迷宫
- ASP.NET MVC
- Less的!important关键字
- Spring简介
- ASP.NET MVC
- Java集合框架07--HashMap和源码分析
- 使用JDK9无法打开eclipse解决方案
- 唯快不破:TCP/IP详解--三次握手和四次握手 Dos攻击