• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

RomanLin

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

【摩尔投票】LeetCode 229. 多数元素 II

题目

https://leetcode.cn/problems/majority-element-ii/description/

题解

在一个长为 \(n\) 的数组中,如果有一个数的出现次数会超过 \(\frac{n}{2}\) 次,用多阵营厮杀的观念来看待,超过 \(\frac{n}{2}\) 次的为胜方阵营,其他阵营就统一视为败方阵营,规则为一个胜方阵营的士兵可以与败方阵营的一个士兵同归于尽,由于胜方阵营的人数大于 \(\frac{n}{2}\),因此最后肯定还有剩余士兵存活。

推广到在一个长为 \(n\) 的数组中,如果有两个数的出现次数会超过 \(\frac{n}{3}\) 次,就可以用维护两个变量,视为两个阵营,然后再用两个变量维护这两个变量的剩余存活人数。若新枚举的士兵,可以成立一个新的阵营(也就是存在无人存活的阵营),就用变量维护它;否则判断是否属于已存在的阵营,若是则增加人数,否则两个阵营都需要牺牲一个士兵。最后剩余的,便是出现次数超过 \(\frac{n}{3}\) 的。

时间复杂度:\(O(n)\)
空间复杂度:\(O(1)\)

参考代码

class Solution {
private:
    const int INF = 0x3f3f3f3f;

public:
    vector<int> majorityElement(vector<int>& nums) {
        vector<int> ans;
        int x = INF, y = INF, cnt_x = 0, cnt_y = 0, sz = nums.size();
        for (auto &it: nums) {
            if (it != y && (!cnt_x || it == x)) {
                x = it;
                ++ cnt_x;
            } else if (it == y || !cnt_y) {
                y = it;
                ++ cnt_y;
            } else {
                -- cnt_x;
                -- cnt_y;
            }
        }
        cnt_x = cnt_y = 0;
        for (auto &it: nums) {
            if (it == x) ++ cnt_x;
            else if (it == y) ++ cnt_y;
        }
        if (cnt_x > sz / 3) {
            ans.emplace_back(x);
        }
        if (cnt_y > sz / 3) {
            ans.emplace_back(y);
        }
        return ans;
    }
};

posted on 2025-03-08 18:20  RomanLin  阅读(14)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3