leetCode169多数问题,leetCode229众数问题及实际问题

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
解决方案:一次删掉不同的数,最后如果有多数的话,他会剩下来,反过来不成立
如果不确定是否有多数,那么最后剩下来的数不一定就是多数

public int test(int[] nums){
      int HP=0;//血量
      int candidate=0;//候选人
        for (int num:nums) {
        //当血量为0时,此时的候选人就是该变量
            if(HP==0){
                candidate=num;
                HP=1;
            }else if(num!=candidate){//如果有候选,当此时的变量和候选人相同时,血量加1;
                HP--;
            }else{//不一样则减1
                HP++;
            }
        }
        //如果到最后没有候选人
        if (HP==0){
            return  -1;
        }
        //如果到最后有候选人,则再遍历一遍,看该数在数组中共出现了几次
        int count=0;
        for (int num:nums) {
            if (num==candidate){
                count++;
            }
        }
		int n=nums.length;
        return count>(n>>1)?candidate:-1;
    }

此方法也叫做摩尔投票法
由此可以的延伸出一到实际问题
美国投票选总统,有很多人来参加,只有当某个人得到了大于全国人的一半以上时才可以当选,每个人都用信封写的某个人,但是我们不知道,此时我们有个机器,他可以识别两个信封里面写的人一样不一样,此时就可以用这个多数问题来解决。
众数问题
给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素

 public List<Integer> majorityElement(int[] nums) {
        //定义一个list,最后将众数放入到list中,
        List list=new ArrayList();
        //因为要的终须需要超过n/3,所以最多有两个众数,最少一个也没有
        int candidate1=nums[0];
        int candidate2=nums[0];
        int HP1=0,HP2=0;
        for (int num:nums) {
			//candidate1和candidate2是同一个值,但是第一次循环时,走的是这一个
            if(candidate1==num){
                HP1++;
                continue;
            }

            if(candidate2==num){
                HP2++;
                continue;
            }
			//当遇到第一个不等同candidate1(candidate2)时,不走这一个,因为此时HP1不等于0,而是等于1
            if(HP1==0){
                candidate1=num;
                HP1++;
                continue;
            }
            //第一次遇到不等于candidate1(candidate2)的数是走的是这一个
            if(HP2==0){
                candidate2=num;
                HP2++;
                continue;
            }
			//当都不等于candidate1和candidate2时,HP1和HP2的血同时减一
            HP1--;
            HP2--;

        }
		
        //计数阶段,找到了两个候选人之后,需要确定票数是否满足大于 N/3
        HP1=0;
        HP2=0;
        for(int num:nums){
            if(num==candidate1){
                HP1++;
            }else if(num==candidate2){
                HP2++;
            }
        }
        int n=nums.length;
        if(HP1>n/3) list.add(candidate1);
        if(HP2>n/3) list.add(candidate2);
        return list;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值