两道数组算法题复盘:多数元素 & 颜色分类

前言

今天复盘两道面试高频的数组题,一道是利用摩尔投票算法的经典题「多数元素」 ,另一道是荷兰国旗问题的典型应用「颜色分类」。这两道题分别代表了 "特殊条件下的最优解" 和 "原地排序的双指针技巧",是数组处理中非常实用的算法模板。


一、169. 多数元素(简单)

题目描述

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊n/2⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。

核心思路:摩尔投票算法

摩尔投票算法的核心思想是 **"正负抵消"**:因为多数元素的出现次数超过一半,所以它在和其他元素两两抵消后,最终一定会剩下。

  1. 维护一个候选元素 candidate 和它的票数 count
  2. 遍历数组:
    • count == 0,将当前元素设为新的候选
    • 若当前元素等于候选,count++;否则 count--
  3. 遍历结束后,candidate 就是多数元素

完整代码(Java)

java

运行

复制代码
class Solution {
    public int majorityElement(int[] nums) {
        int candidate = nums[0];
        int count = 1;
        for (int i = 1; i < nums.length; i++) {
            if (count == 0) {
                candidate = nums[i];
                count = 1;
            } else if (nums[i] == candidate) {
                count++;
            } else {
                count--;
            }
        }
        return candidate;
    }
}

复杂度分析

  • 时间复杂度:O (n),仅需一次遍历数组
  • 空间复杂度:O (1),仅使用常数额外空间

拓展思考

摩尔投票算法还可以拓展到 "找出数组中出现次数大于 n/3 的元素",最多有两个候选元素,需要两轮遍历:第一轮投票找出候选,第二轮验证是否满足条件。


二、75. 颜色分类(中等)

题目描述

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。 我们使用整数 012 分别表示红色、白色和蓝色。 注意:不能使用库函数来排序,必须原地解决。

核心思路:双指针(荷兰国旗问题)

这道题的最优解法是三指针原地交换,核心思想是:

  • 定义 p0 指向 0 元素的右边界,p2 指向 2 元素的左边界,curr 指向当前遍历元素
  • 遍历数组:
    • nums[curr] == 0,将其与 nums[p0] 交换,p0++curr++
    • nums[curr] == 2,将其与 nums[p2] 交换,p2--(此时 curr 不前进,因为交换过来的元素还需要判断)
    • nums[curr] == 1,直接 curr++

完整代码(Java)

java

运行

复制代码
class Solution {
    public void sortColors(int[] nums) {
        int p0 = 0, curr = 0;
        int p2 = nums.length - 1;
        while (curr <= p2) {
            if (nums[curr] == 0) {
                swap(nums, curr, p0);
                p0++;
                curr++;
            } else if (nums[curr] == 2) {
                swap(nums, curr, p2);
                p2--;
            } else {
                curr++;
            }
        }
    }

    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

复杂度分析

  • 时间复杂度:O (n),仅需一次遍历数组
  • 空间复杂度:O (1),原地交换,未使用额外空间

拓展思考

荷兰国旗问题可以拓展到更多颜色的排序场景,核心思想都是通过指针将元素分区,一次遍历完成排序,避免了多次遍历或额外空间的开销。


两道题对比总结

表格

题目 核心思想 时间复杂度 空间复杂度 关键考点
多数元素 摩尔投票算法(正负抵消) O(n) O(1) 多数元素的定义、投票过程
颜色分类 三指针原地分区(荷兰国旗问题) O(n) O(1) 双指针技巧、原地交换
相关推荐
小欣加油7 小时前
leetcode56 合并区间
c++·算法·leetcode·职场和发展
lqqjuly7 小时前
前沿算法深度解析(二)
人工智能·算法·机器学习
徐小夕8 小时前
万字长文!千万级文档 RAG 知识库系统落地实践
前端·算法·github
akunkuntaimei8 小时前
2026年高考数学各省真题及答案(完整版)
算法·高考
Hello:CodeWorld9 小时前
C 风格变参 vs C++ 变参模板:核心区别与选型指南
c语言·c++·算法
8Qi810 小时前
LeetCode 516:最长回文子序列
算法·leetcode·职场和发展·动态规划
youngerwang11 小时前
【从搬运工到协处理器:网卡芯片架构、算法、验证与边缘演进深度剖析】
网络·算法·架构·芯片
KaMeidebaby12 小时前
卡梅德生物技术快报|纯化重组蛋白实操详解
人工智能·python·tcp/ip·算法·机器学习
手写码匠13 小时前
从零实现 Prompt 工程引擎:结构化提示、自动优化与多轮自省体系
人工智能·深度学习·算法·aigc
无限码力13 小时前
阿里算法岗 0530笔试真题 - 多约束条件下的元素匹配统计
算法·阿里笔试真题·阿里机试真题·阿里算法岗笔试