leetcode MajorityElement相关问题

题目: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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值