Question
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.
本题难度Easy。有3种算法分别是:哈希法、排序法、投票法(最巧妙)
【题意】
You may assume that the array is non-empty and the majority element always exist in the array.
1、哈希法
【复杂度】
时间 O(N) 空间 O(N)
【思路】
在遍历数组的过程中,用一个哈希表记录每个数出现过的次数,如果该次数大于一半,则说明是众数。
【代码】
public class Solution {
public int majorityElement(int[] nums) {
//require
int size=nums.length;
Map<Integer,Integer> map=new HashMap<>();
//invariant
for(int n:nums){
if(map.containsKey(n)){
if(map.get(n)==size/2)return n;
map.put(n,map.get(n)+1);
}else
map.put(n,1);
}
//ensure
return nums[0];//这是针对只有1个元素情况
}
}
2、排序法
【复杂度】
时间 O(NlogN) 空间 O(1)
【思路】
将数组排序,这时候数组最中间的数肯定是众数。
【代码】
public class Solution {
public int majorityElement(int[] nums) {
//require
Arrays.sort(nums);
//ensure
return nums[nums.length/2];
}
}
3、投票法
【复杂度】
时间 O(N) 空间 O(1)
【思路】
设一个投票变量candidate
,还有一个计数变量cnt
,开始遍历数组。如果新数和candidate
一样,那么cnt
加上1;否则,如果cnt==1
,则将candidate
更新为这个新的数,如果cnt>1
,则cnt
减去1。因为每一对不一样的数都会互相消去,最后留下来的candidate
就是众数。
【代码】
public class Solution {
public int majorityElement(int[] nums) {
//require
int size=nums.length;
int candidate=nums[0],cnt=1;
//invariant
for(int i=1;i<size;i++){
int n=nums[i];
if(n==candidate)cnt++;
else if(cnt==1)candidate=n;
else cnt--;
}
//ensure
return candidate;
}
}