两道位运算 / 摩尔投票经典题复盘:只出现一次的数字 & 多数元素

前言

今天复盘两道 LeetCode 上的经典 "简单题",它们看起来容易,但解法里藏着非常巧妙的算法思想:一道是位运算的经典应用 ,另一道是摩尔投票算法的入门模板。这两道题不仅是面试高频考点,更是理解算法优化思路的绝佳案例。


一、136. 只出现一次的数字(简单)

题目描述

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 要求:线性时间复杂度、常数额外空间。

核心思路:异或运算的妙用

这道题的 "黑科技" 解法,核心是利用异或运算的三个性质:

  1. a ^ a = 0:相同的数异或结果为 0
  2. a ^ 0 = a:任何数和 0 异或,结果不变
  3. a ^ b ^ a = b:异或运算满足交换律和结合律

所以,我们只需要把数组里的所有数从头到尾异或一遍,最终的结果就是那个只出现一次的数字 ------ 所有成对出现的数都会异或为 0,最后剩下的就是那个单独的数。

完整代码(Java)

java

运行

复制代码
class Solution {
    public int singleNumber(int[] nums) {
        int res = 0;
        for (int num : nums) {
            res ^= num;
        }
        return res;
    }
}

复杂度分析

  • 时间复杂度:O (n),只遍历一次数组
  • 空间复杂度:O (1),只用了一个变量存结果

拓展思考

如果题目改成 "其余元素出现三次,只有一个元素出现一次",就不能直接用异或了,需要用位统计的方法,但核心思路依然是利用位运算的特性。


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

题目描述

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊n/2⌋ 的元素。 要求:线性时间复杂度、O (1) 空间复杂度。

核心思路:摩尔投票算法

这道题的最优解是摩尔投票算法,它的核心思想可以理解为 "正负抵消":

  • 维护一个候选元素 candidate 和它的票数 count
  • 遍历数组:
    • 如果 count == 0,把当前元素设为新的候选
    • 如果当前元素等于候选,count++;否则 count--
  • 因为多数元素的出现次数超过一半,它在和其他元素 "抵消" 后,最终一定会成为剩下的候选。

完整代码(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 的元素",最多有两个候选元素,需要两轮遍历:第一轮投票找出候选,第二轮验证是否真的满足条件。


两道题对比总结

表格

题目 核心思想 时间复杂度 空间复杂度 关键考点
只出现一次的数字 异或运算的性质 O(n) O(1) 位运算、交换律结合律
多数元素 摩尔投票算法(正负抵消) O(n) O(1) 多数元素的定义、投票过程

这两道题都是 "看起来简单,解法很巧妙" 的典型,掌握它们的思路,不仅能解决原题,更能帮你理解算法优化的核心思想 ------ 利用问题的特性,用更高效的方式实现目标。

相关推荐
坚持编程的菜鸟5 小时前
模拟实现strncat
c语言·算法·模拟实现strncat
wabs6665 小时前
关于哈希表【力扣1.两数之和的思考】
数据结构·算法·leetcode·散列表·图论
大辉狼_音频架构5 小时前
第 02 篇:时域的语言 —— 卷积、LTI 系统与冲激响应
算法·音视频开发
Hhy_11075 小时前
【从零开始学数据结构 ⑥】:二叉树之堆——打破规则的优先队列
c语言·开发语言·数据结构·学习·visual studio
星轨初途6 小时前
LeetCode 热题 100——day7 接雨水
数据结构·c++·笔记·算法·leetcode·职场和发展
qeen876 小时前
【数据结构】搜索二叉树的介绍与算法原理解析及实现
数据结构·c++·学习·算法·模板
阳明山水6 小时前
销量预测的“隐形杀手”:概念漂移与自适应学习实战
人工智能·深度学习·算法·机器学习·架构
szarron6 小时前
HT666 0.6-6GHz 定向高增益手持天线:EMC 测试与频谱定位实战指南
网络·算法·5g·信号处理·射频工程·频谱仪
liulilittle6 小时前
反量化:反量化Q8零(q8_0)
人工智能·算法·机器学习·ai·llm
青 春 记 忆12 小时前
LeetCode 21. 合并两个有序链表|Python 解法详解
python·算法·leetcode·链表