• 求众数——摩尔投票


    摩尔投票算法

    摩尔投票法适用于求解“数组中出现次数大于n/2,n/3,...的元素”的问题。它的思想是对拼消耗,从第一选手开始闯关,遇到“非我同类”就“同归于尽”,相反遇到“同类”就相伴而行,最后剩下的选手即为所求的众数。

    不过需要注意的是,并非最后得到的结果即为所求,当前数组并不是一定就存在符合条件的众数(但如果存在的话则它必定是摩尔投票得到的那个结果),因此最后还需要一个验证的过程。

    169.多数元素(求出现次数大于⌊ n/2 ⌋的元素)

    如果当前元素与候选者相同则归队,否则对拼消耗。

        public int majorityElement(int[] nums) {
            //已经确定存在多数元素,因此不再需要验证过程
            //if(nums==null||nums.length==0) return -1;
            int major=nums[0],cnt=0;
            for(int num:nums){
                if(cnt==0){
                    major=num;
                }
                if(num==major) cnt++;
                else cnt--;
            }
            // cnt=0;
            // for(int num:nums){
            //     if(num==major) cnt++;
            // }
            // return cnt>nums.length/2?major:-1;
            return major;
        }
    

    229.求众数 II(求出现次数大于⌊ n/3 ⌋的元素)

    出现次数大于⌊ n/3 ⌋的元素最多有2个,因此需要两个计数器。当前元素如果等于候选者1则与与候选者1归队在一起,如果等于候选者2则与与候选者2归队在一起,如果与两个候选者都不相等,则与两个候选者均对拼消耗一次。需要注意的是两个候选者值必须不等。

        public List<Integer> majorityElement(int[] nums) {
            List<Integer> res=new ArrayList<>();
            if(nums==null||nums.length==0) return res;
            int major1=nums[0],major2=nums[0],cnt1=0,cnt2=0;
            for(int num:nums){
                //即便一开始num==major1==major2,最后major1和major2也是必不相等的。
                if(num==major1) cnt1++;
                else if(num==major2) cnt2++;
                else if(cnt1==0) {
                    major1=num;
                    cnt1++;
                }
                else if(cnt2==0) {
                    major2=num;
                    cnt2++;
                }
                else{
                    cnt1--;
                    cnt2--;
                }
            }
            cnt1=0;
            cnt2=0;
            for(int num:nums){
                if(num==major1) cnt1++;
                if(num==major2) cnt2++;
            }
            if(cnt1>nums.length/3) res.add(major1);
            if(cnt2>nums.length/3&&major1!=major2) res.add(major2);
            return res;
        }
    

    扩展(求出现次数大于⌊ n/k ⌋的元素)

    需要k-1个计数器。当前元素如果等于候选者i则与与候选者i归队在一起,否则与k-1个候选者均对拼消耗一次。

  • 相关阅读:
    C#获取局域网MAC地址
    查看Linux是32位还是64位的方法
    JS判断不能为空实例代码
    SQL2005数据库行列转换
    mysql 导入导出数据库、数据表的方法
    linux kill 关闭进程命令
    设置CentOS控制台分辨率图文详解
    Windows 2003 IIS 不支持ASP问题的解决方法
    稳聘App设计图分享
    Sql 中存储过程详细案例
  • 原文地址:https://www.cnblogs.com/Frank-Hong/p/14992896.html
Copyright © 2020-2023  润新知