leetcode-169-求众数 (majority element)-java

题目及测试

package pid169;
/*求众数

给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在众数。

示例 1:

输入: [3,2,3]
输出: 3

示例 2:

输入: [2,2,1,1,1,2,2]
输出: 2



*/


public class main {
	
	public static void main(String[] args) {
		int[][] testTable = {{3,2,3},{2,2,1,1,1,2,2},{1,2,1}};
		for (int[] ito : testTable) {
			test(ito);
		}
	}
		 
	private static void test(int[] ito) {
		Solution solution = new Solution();
		int rtn;
		long begin = System.currentTimeMillis();
		for (int i = 0; i < ito.length; i++) {
		    System.out.print(ito[i]+" ");		    
		}
		System.out.println();
		//开始时打印数组
		
		rtn = solution.majorityElement(ito);//执行程序
		long end = System.currentTimeMillis();	
		
		//System.out.println(ito + ": rtn=" + rtn);
		System.out.println(": rtn=" +rtn);
		
		
		System.out.println();
		System.out.println("耗时:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

解法1(成功,27ms,很慢)

用hashmap装入key为数字,value为数字出现的个数,当加入的value大于mid时返回now

时间o(n) 空间o(n)

 

package pid169;

import java.util.HashMap;

public class Solution {
public int majorityElement(int[] nums) {
    int length=nums.length;
    int mid=length/2;
    HashMap<Integer, Integer> map=new HashMap<>();
    for(int i=0;i<length;i++){
    	int now=nums[i];
    	Integer nowNum;
    	if(map.containsKey(now)){
    		nowNum=map.get(now);   
    		nowNum++;
    	}
    	else{
    		nowNum=1;
    	}
    	if(nowNum>mid){
    		return now;
    	}
    	map.put(now, nowNum);
    }
    return 0;
    }
}

 

解法3(成功,2ms。极快)

摩尔投票算法

假设有这样一个场景:票选村长,每人可投一票,我们将候选村长从1开始编号,村民们在票上写上候选村长的编号即可完成投票。那么最后统计的票可形成一个整型数组。那么谁是村长呢?票数过半的那个人。

摩尔投票算法可以快速的计算出一个数组中出现次数过半的数即大多数(majority),算法核心思想是同加,异减。我们举个例子。

假设数组是:[1,2,1,1,2,1]。算法步骤如下:

    1。当前大多数是1,得分置1
    2。与当前大多数不同,得分 - 1,得分为0,当前大多数 = 1
    1。与当前大多数不同,得分为0,所以设置当前大多数 1 -> 1,得分置1
    1。与当前大多数相同,得分 + 1,得分为2,当前大多数 = 1
    2。与当前大多数不同,得分 - 1 ,得分为1,当前大多数 = 1
    1。与当前大多数相同,得分 + 1,得分为2,当前大多数 = 1

这意味着1是这个数组中出现次数过半的数。

可以感受得到,算法会保存一个当前大多数,和得分,当遇到一个数不是当前大多数时,得分会减一,当减到0时,大多数会发生改变,并且重置得分为1。
 

    public int majorityElement(int[] nums) {
        int length=nums.length;
        if(length==0){
        	return 0;
        }
        if(length==1){
        	return nums[0];
        }
        int num=nums[0];
        int counts=1;
        for(int i=1;i<length;i++){
        	int now=nums[i];
        	// 已经冲掉了,新的进入
        	if(counts==0){
        		num=now;
        		counts=1;
        		continue;
        	}
        	if(now==num){
        		// 是同一个数字
        		counts++;
        		continue;
        	}else{
        		// 不是同一个数字
        		counts--;
        		continue;
        	}
        	
        }
    	
    	return num;
    }	

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值