题目:MajorityElement
Given an array of size n, find the majority element. The majority element is the element that appears more than n/2 times.
那么如果超过n/3的呢?那么我们需要两个计数器,代码如下
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.
解决方法:moore voting algorithm
假设第一个数是major,count=1,从第二个数开始遍历,如果与major相同则count++,else则count--。如果count==0,那么表面前面的数中没有那个数超过一半以上,整个问题是上面这一过程的子问题,那么只要重复上面一个过程就好了
code:
public int majorityElement2(int[] nums) {
//moore voting algorithm
int major = nums[0],count=1;
for(int i=1;i<nums.length;i++){
if(count==0){
major = nums[i];
}
if(nums[i]==major)
count++;
else count--;
}
return major;
}
那么如果超过n/3的呢?那么我们需要两个计数器,代码如下
/**
* 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.
* @param nums
* @return
*/
public List<Integer> majorityElement(int[] nums) {
List<Integer> res = new ArrayList<Integer>();
int m = 0, n = 0, cm = 0, cn = 0;
for (int a : nums) {
if (a == m) {
++cm;
} else if (a == n) {
++cn;
} else if (cm == 0) {
m = a;
cm = 1;
} else if (cn == 0) {
n = a;
cn = 1;
} else {
--cm;
--cn;
}
}
cm = cn = 0;
for (int a : nums){
if (a == m) {
++cm;
} else if (a == n) {
++cn;
}
}
if (cm > nums.length / 3) {
res.add(m);
}
if (cn > nums.length / 3) {
res.add(n);
}
return res;
}
那么如果再一般化一点,不超过n/k呢
/*
* 思路:
* 从头开始,如果遇到2个不同的数,就都删除,一直到最后,剩下的数就是出现次数大于n/2的。
* 可以推广到找出现次数大于n/k的情况,即遇到k个不同的数,删除,剩下的数就是出现次数大于n/k的。
*/
public List<Integer> majorityElement3(int[] nums,int k) {
List<Integer> res = new ArrayList<Integer>();
int d = 0;//记录遇到不同数的个数,if d==k,则将map中元素的个数减一
Map<Integer, Integer> map = new HashMap<Integer, Integer>();//<k,c> k为元素,c为元素出现的次数
for(int i=0;i<nums.length;i++){
if(!map.containsKey(nums[i])){
map.put(nums[i], 1);
d++;
if(d==k){
Iterator<Integer> it = map.keySet().iterator();
while(it.hasNext()){
int key = it.next();
if(map.get(key)>=1)
map.put(key, map.get(key)-1);
if(map.get(key)==0){
//map.remove(key);
it.remove();
d--;
}
}
}
}else{
map.put(nums[i], map.get(nums[i])+1);
}
}
//map中目前存放可能可能超过n/k的元素,需要在遍历一遍确认
Iterator<Integer> it = map.keySet().iterator();
while(it.hasNext()){
int key = it.next();
map.put(key, 0);//将map的的元素出现的次数改为0
}
for(int n:nums){
if(map.containsKey(n))
map.put(n, map.get(n)+1);//统计元素出现的次数
}
it = map.keySet().iterator();//判断元素出现的次数是否超过n/k
while(it.hasNext()){
int key = it.next();
if(map.get(key)>nums.length/k)
res.add(key);
}
return res;
}