leetcode MajorityElement相关问题

来源:互联网 发布:顾家北和慎小嶷 知乎 编辑:程序博客网 时间:2024/05/21 11:09
题目:MajorityElement
 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; }


0 0
原创粉丝点击