摩尔投票,leetcode169,leetcode229

摩尔投票

初步认识

涉及题目

LeetCode 169 - Majority Element

算法概述

在给定的数组中,找出其中出现次数超过n/2的元素。题目假定一定存在一个元素出现超过n/2次。

思路

每次删除数组中两个不相同的元素,遍历完数组后,剩下的元素一定是出现超过n/2次的元素。

  • 定义候选者cand赋任意值、计数器count初始化为0
  • 遍历数组
    • 如果count值为0,将cand赋值为当前值nums[i]count赋值为1
    • 如果count值不为0,且当前值nums[i]等于cand的值,则count加一,否则count减一
  • 遍历完成后,cand即为所求元素

count减一可以理解为在数组中删掉了当前元素nums[i]和一个cand的元素,当count元素为0时可以理解为前面的所有数都已经相互抵消。

代码实现

public int majorityElement(int[] nums) {
    int cand = 0;
    int count = 0;
    for (int i = 0; i< nums.length; ++i) {
        if (count == 0) {
            count = 1;
            cand = nums[i];
            continue;
        }
        if (cand == nums[i]) count++;
        else count--;
    }
    return cand;
}

进阶

涉及题目

LeetCode 229 - Majority Element II

思路

题目要找出出现次数大于n/3的元素,但并不保证元素一定存在。

每次删除三个不同元素,最后留下的(最多两个)一定是出现次数最多的,但不一定大于n/3次,还需要再遍历一次数组计数是否大于n/3。由此可推出超过n/k的元素(最多k-1个)。

  • 定义候选者cand1cand2赋任意值、计数器count1count2初始化为0
  • 遍历数组第一次找出可能的元素
    • 如果当前值nums[i]等于cand1cand2的值,则对应的count1count2加一
    • 如果count1count2值为0,将cand1cand2赋值为当前值nums[i],对应count赋值1
    • 否则count1count2均减一
  • count1count2赋值为0
  • 遍历数组第二次判断是否满足条件(出现次数大于n/3
    • 判断nums[i]是否与cand1cand2相等,相等则对应count加一
  • 最终大于n/3次数的元素即为所求

代码实现

public List<Integer> majorityElement(int[] nums) {
    List<Integer> result = new ArrayList<>();
    if (nums.length == 0) return result;
    int cand1 = 0;
    int cand2 = 0;
    int count1 = 0;
    int count2 = 0;
    for (int i = 0; i < nums.length; ++i) {
        if (cand1 == nums[i]) {
            count1++;
            continue;
        }
        if (cand2 == nums[i]) {
            count2++;
            continue;
        }
        if (count1 == 0) {
            count1 = 1;
            cand1 = nums[i];
            continue;
        }
        if (count2 == 0) {
            count2 = 1;
            cand2 = nums[i];
            continue;
        }
        count1--;
        count2--;
    }

    count1 = 0;
    count2 = 0;
    for (int i = 0; i < nums.length; ++i) {
        if (cand1 == nums[i]) count1++;
        else if (cand2 == nums[i]) count2++;
        //一定要else if,因为cand1和cand2可能是相同元素
    }
    if (count1 > (nums.length)/3) result.add(cand1);
    if (count2 > (nums.length)/3) result.add(cand2);

    return result;
}

参考资料

摩尔投票算法( Boyer-Moore Voting Algorithm)

LeetCode 0169 Majority Element

LeetCode 0229 Majority Element II 摩尔投票

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值