超级水王问题 详解

水王问题 历史和由来可自行百度
抽象问题为:
这里写图片描述

奉上代码 即详细注释:

* 思想 :如果在一个数组中存在一个出现次数大于一半的数
 * 每次删除两个不同的数 到最后剩下的肯定是这个数 不可能是其他是数
 */
public class superId {
    public static void main(String[] args) {
        int [] arr = {2,5,2,7,2,1,2};
        printHalfMajor(arr);
    }
    public static void printHalfMajor(int [] arr) {
        int cand = 0;//候选元素   相当于老怪 不断有新的英雄出现 只要跟他不一样就同归于尽 即同时删去了两个不同的数
        int times = 0;//剩余节点数  相当于老怪的生命条数 每次出现相同的数 生命条数就加1 然后出现不同的数就同归于尽 就减少一条生命
        //同时删除两个不同的数
        for (int i = 0; i != arr.length; i++) {
            //1.还没有候选数(就是从第一个数开始)连续出现两个不同的数 则直接删去
            if (times == 0) { //如果剩余的数为0  即 没有相同的数
                cand = arr[i]; //则当前的数作为候选数
                times = 1;     //候选数的剩余节点加1
                //2.有候选数了 出现了一个和候选数相同的数 则不删除 增加
                //候选数的剩余点数
            } else if (arr[i] == cand) { //当节点数不为0 且出现相同的候选数时
                times++;   //候选数的节点数加1 即出现相同的数了
                //当存在候选数 然后出现的数与候选数不同 则删除当前数 并带走候选数的一条命
                //即候选点数减1
            } else {   //当节点数不为0  且当前出现的数和候选数不同时
                times--; //候选数的节点数减1
            }
        }
        //因为上一个for循环中 如果数组都是不同的数 也会返回一个值 就是最后那个数
        //所以需要下面的判断
//        times = 0;
        for (int i = 0; i != arr.length; i++) {
            if (arr[i] == cand) {  //到这一步cand已经知道 只是判断是否是多余一半的数
                times++;
            }
        }
        if (times > arr.length / 2) {
            System.out.println(cand);
        } else {
            System.out.println("no such number.");
        }
    }
}

测试结果为:2;
注:通过左神的讲解 深刻理解的 膜拜左神!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值