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.
排序法
思路
将数组排序,这时候数组最中间的数肯定是众数。
public class Solution1 {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length / 2];
}
}
投票法
思路
记录一个elem变量,还有一个count变量,开始遍历数组。如果新数和elem一样,那么count加上1,否则的话,如果count不是0,则count减去1,如果count已经是0,则将candidate更新为这个新的数。因为每一对不一样的数都会互相消去,最后留下来的elem就是众数。
public class Solution2 {
public int majorityElement(int[] nums) {
int elem=0;
int count=0;
for (int i=0;i<nums.length;i++){
if (count==0){
elem=nums[i];
count=1;
}else {
if (elem==nums[i])
count++;
else
count--;
}
}
return elem;
}
}
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.
投票法
上一题中,超过一半的数只可能有一个,所以我们只要投票出一个数就行了。而这题中,超过n/3的数最多可能有两个,所以我们要记录出现最多的两个数。同样的两个elem和对应的两个count,如果遍历时,某个候选数和到当前数相等,则给相应计数器加1。如果两个计数器都不为0,则两个计数器都被抵消掉1。如果某个计数器为0了,则将当前数替换相应的候选数,并将计数器初始化为1。最后我们还要遍历一遍数组,确定这两个出现最多的数,是否都是众数。
public class Solution {
public List<Integer> majorityElement(int[] nums) {
List<Integer> result=new LinkedList<>();
if(nums==null||nums.length==0)return result;
int elem1=0,count1=0,elem2=0,count2=0;
for(int i=0;i<nums.length;i++){
if(nums[i]==elem1){
count1++;
}else if(nums[i]==elem2){
count2++;
}else if(count1!=0&&count2!=0){
count1--;
count2--;
}else{
if(count1==0){
elem1=nums[i];
count1=1;
}else{
elem2=nums[i];
count2=1;
}
}
}
//上面只是计算出最多的两个数,接下来计算出出现的次数是否超过n/3
count1=0;
count2=0;
for(int i=0;i<nums.length;i++){
if(nums[i]==elem1)count1++;
else if(nums[i]==elem2)count2++;
}
if(count1>nums.length/3)result.add(elem1);
if(count2>nums.length/3)result.add(elem2);
return result;
}
}