Majority Element I
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.
哈希表法
复杂度
时间 O(N) 空间 O(N)
思路
在遍历数组的过程中,用一个哈希表记录每个数出现过的次数,如果该次数大于一半,则说明是众数。
排序法
复杂度
时间 O(NlogN) 空间 O(1)
思路
将数组排序,这时候数组最中间的数肯定是众数。
代码
public class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length / 2];
}
}
位操作法
复杂度
时间 O(N) 空间 O(1)
思路
假设一个数是最多只有32位的二进制数,那么我们从第一位到第32位,对每一位都计算所有数字在这一位上1的个数,如果这一位1的个数大于一半,说明众数的这一位是1,如果小于一半,说明大多数的这一位是0。
投票法
复杂度
时间 O(N) 空间 O(1)
思路
记录一个candidate变量,还有一个counter变量,开始遍历数组。如果新数和candidate一样,那么counter加上1,否则的话,如果counter不是0,则counter减去1,如果counter已经是0,则将candidate更新为这个新的数。因为每一对不一样的数都会互相消去,最后留下来的candidate就是众数。
代码
public class Solution {
public int majorityElement(int[] nums) {
int candidate = nums[0], cnt = 0;
for(int i = 1; i < nums.length; i++){
if(candidate == nums[i]){
cnt++;
} else if(cnt==0){
candidate = nums[i];
} else {
cnt--;
}
}
return candidate;
}
}
Majority Element II
Given an integer array of size n, find all elements that appear more than
⌊ n/3 ⌋
times. The algorithm should run in linear time and in O(1) space.
投票法
复杂度
时间 O(N) 空间 O(1)
思路
上一题中,超过一半的数只可能有一个,所以我们只要投票出一个数就行了。而这题中,超过n/3的数最多可能有两个,所以我们要记录出现最多的两个数。同样的两个candidate和对应的两个counter,如果遍历时,某个候选数和到当前数相等,则给相应计数器加1。如果两个计数器都不为0,则两个计数器都被抵消掉1。如果某个计数器为0了,则将当前数替换相应的候选数,并将计数器初始化为1。最后我们还要遍历一遍数组,确定这两个出现最多的数,是否都是众数。
代码
public class Solution {
public List<Integer> majorityElement(int[] nums) {
List<Integer> res = new ArrayList<Integer>();
if(nums.length == 0) return res;
int c1 = 1, c2 = 0, n1 = nums[0], n2 = 0;
for(int i = 1; i < nums.length; i++){
// 如果和某个候选数相等,将其计数器加1
if(nums[i] == n1){
c1++;
} else if(nums[i] == n2){
c2++;
// 如果都不相等,而且计数器都不为0,则计数器都减1
} else if(c1 != 0 && c2 != 0){
c1--;
c2--;
// 如果某个计数器为0,则更新相应的候选数
} else {
if(c1 == 0){
n1 = nums[i];
c1 = 1;
} else {
n2 = nums[i];
c2 = 1;
}
}
}
c1 = 0;
c2 = 0;
for(int i = 0; i < nums.length; i++){
if(nums[i] == n1) c1++;
else if(nums[i] == n2) c2++;
}
if(c1 > nums.length / 3) res.add(n1);
if(c2 > nums.length / 3) res.add(n2);
return res;
}
}