编程之美2.3节。正好对应leetcode上的第169题Majority Element和229题Majority Element II,该类问题可以总结为线性时间查找固定频率元素,应该使用Moore's voting algorithm,详细说明见链接。
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.
public static int majorityElement(int[] nums) {
int re=0;
int count=0;
for(int i=0; i<nums.length; i++){
if(count==0){
re=nums[i];
count=1;
}else{
if(nums[i]==re){
count++;
}else{
count--;
}
}
}
return re;
}
229. 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.
public static List<Integer> majorityElement(int[] nums) {
List<Integer> re=new ArrayList<Integer>();
int[] num=new int[2];
int count0=0;
int count1=0;
for(int i=0; i<nums.length; i++){
if(num[0]==nums[i]){
count0++;
}else if(num[1]==nums[i]){
count1++;
}else if(count0==0){
count0=1;
num[0]=nums[i];
}else if(count1==0){
count1=1;
num[1]=nums[i];
}else{
count0--;
count1--;
}
}
count0=0;
count1=0;
for(int i=0; i<nums.length; i++){
if(nums[i]==num[0]){
count0++;
}else if(nums[i]==num[1]){
count1++;
}
}
if(count0>nums.length/3){
re.add(num[0]);
}
if(count1>nums.length/3){
re.add(num[1]);
}
return re;
}
总结:两个问题基本一样,核心思想就是频率超过n/3的数组肯定只有两个,所以建立一个长度为2的数组num,还有两个变量count0和count1分别记录num[0]和num[1]元素出现的次数,遍历一次以后数组中两个元素肯定是出现频率最高的两个,最后再遍历一次看数组中的元素是否满足超过n/3的要求。