当前位置: 首页 > backend >正文

LeetCode 137 有限状态自动机解法原理详解

LeetCode 137 有限状态自动机解法原理详解
在LeetCode 137题中,有限状态自动机解法通过巧妙的位运算实现了对"只出现一次的数字"的高效查找。下面从状态定义、状态转移、数学原理三个层面详细解析:
一、状态机的核心定义
ones:记录出现1次的二进制位集合。
twos:记录出现2次的二进制位集合。
状态转移目标:
当数字第一次出现时,将对应位存入ones。
当数字第二次出现时,将对应位从ones移至twos。
当数字第三次出现时,将对应位从twos清零(即消除该数字的影响)。
二、状态转移方程解析

  1. ones = (ones ^ num) & ~twos
    ones ^ num:
    对ones和num进行异或运算,相当于:
    若num的某一位为1且该位在ones中为0,则ones的该位变为1(数字第一次出现)。
    若num的某一位为1且该位在ones中为1,则ones的该位变为0(数字第二次出现,准备移至twos)。
    & ~twos:
    用twos的按位取反进行与运算,确保:
    若twos的某一位为1(数字已出现2次),则ones的该位强制置为0(避免重复记录)。
    总结:
    该操作实现了"数字第一次出现时记录到ones,第二次出现时从ones移除"的逻辑。
  2. twos = (twos ^ num) & ~ones
    twos ^ num:
    对twos和num进行异或运算,相当于:
    若num的某一位为1且该位在twos中为0,则twos的该位变为1(数字第二次出现,从ones移至此)。
    若num的某一位为1且该位在twos中为1,则twos的该位变为0(数字第三次出现,准备清零)。
    & ~ones:
    用ones的按位取反进行与运算,确保:
    若ones的某一位为1(数字刚出现1次),则twos的该位强制置为0(防止提前记录)。
    总结:
    该操作实现了"数字第二次出现时记录到twos,第三次出现时从twos移除"的逻辑。
    三、状态转移示例:数字出现三次
    以数字x为例,分析其三位状态变化:
  3. 第一次出现x
    ones:0 ^ x = x,& ~twos(此时twos=0)→ ones = x
    twos:0 ^ x = x,& ~ones(此时ones=x)→ twos = x & ~x = 0
    状态:ones=x, twos=0(记录x出现1次)
  4. 第二次出现x
    ones:x ^ x = 0,& ~twos(twos=0)→ ones = 0
    twos:0 ^ x = x,& ~ones(ones=0)→ twos = x
    状态:ones=0, twos=x(记录x出现2次)
  5. 第三次出现x
    ones:0 ^ x = x,& ~twos(twos=x)→ x & ~x = 0
    twos:x ^ x = 0,& ~ones(ones=0)→ 0 & ~0 = 0
    状态:ones=0, twos=0(x的影响被消除)
    四、数学原理:三进制计数器
    该状态机本质上是一个三进制计数器,每一位的状态转移如下:
    00(初始状态)→ 出现1次 → 01(ones=1)
    01 → 出现1次 → 10(twos=1)
    10 → 出现1次 → 00(清零)
    用二进制位表示三进制状态:
    ones:最低位(1的权值)
    twos:次低位(3的权值)
    每次出现数字时,对应位的三进制值加1,逢3进0。
    五、位运算的逻辑等价性
    状态转移方程可等价表示为:
    cpp
    运行
    // 三进制计数器的数学表达
    ones = (ones + num) % 3;
    twos = (twos + num) % 3;

// 但位运算实现更高效,且等价于:
ones = (ones ^ num) & ~twos;
twos = (twos ^ num) & ~ones;
证明:
当twos=0时:
ones = (ones ^ num) & ~0 = ones ^ num,等价于ones = (ones + num) % 3(当num=1时,0→1,1→0)。
当ones=0且twos=1时:
ones = (0 ^ num) & ~1 = num & 0 = 0,twos = (1 ^ num) & ~0 = 1 ^ num,等价于twos = (1 + num) % 3(num=1时,1→0)。
六、为什么最终结果是ones?
对于出现三次的数字:其所有二进制位在ones和twos中经历三次翻转后最终为0,不影响结果。
对于只出现一次的数字:其所有二进制位仅在ones中记录为1,twos中为0,因此ones即为该数字。
七、示例验证:nums = [2,2,3,2]
数字2出现三次,数字3出现一次。
二进制位分析(以最低两位为例):
数字2:10
数字3:11
遍历过程:
处理2:ones=10, twos=00
处理2:ones=00, twos=10
处理2:ones=00, twos=00(2的影响消除)
处理3:ones=11, twos=00
最终ones=11,即数字3。
总结
该解法通过位运算模拟了三进制计数器的状态转移,实现了:
对每个数字的出现次数进行模3计数。
只保留出现一次的数字的二进制位。
时间复杂度O(n),空间复杂度O(1),是最优解法。
理解这种状态机思想,有助于解决类似的"出现k次"问题(如出现四次、五次等,只需扩展状态位)。

http://www.xdnf.cn/news/13880.html

相关文章:

  • 测试:AWS SDK for JavaScript v2 迁移到 v3
  • 帆软报表实现层层下钻继承上上层报表参数
  • ollama+docker+dify配置指南
  • CQL3D输入文件及参数解释
  • linux中执行脚本命令的source和“.”和“./”的区别
  • 校园网数据安全防线
  • sed命令在修改Rocky Linux镜像源配置文件中的作用:
  • AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年6月12日第106弹
  • 晶圆搬运机器人与RFID半导体读卡器携手赋能半导体制造高效变革
  • 探索铸铁试验平台在制造行业的卓越价值
  • HALCON第一讲->数据结构、语法规则与思路
  • 深度学习网络入侵检测系统警报
  • RX Clock Correction Attributes
  • 使用freemarker模板 生成 word文档
  • PMP证--开篇
  • AI的镜像:人工智能如何重塑人类认知边界
  • 路由交换技术-思科拓扑搭建
  • 深度解析SerpAPI:AI时代的智能搜索引擎集成方案
  • 农田实时监测与管理系统开发
  • byte数组变量转int变量
  • 一[2]、ubuntu18.04环境 yolov8 + realsenseD435i 实时效果测试
  • Docker 网络模式
  • Doris与DS结合实现MySQL侧的Upsert功能
  • SpringCloud + MybatisPlus:多租户模式与实现
  • Catch2 开源库介绍与使用指南
  • 【threejs】每天一个小案例讲解:常见材质
  • oracle 23ai json简单使用
  • reactive() 和 toRef()
  • 微服务架构中的 Kafka:异步通信与服务解耦(四)
  • 《哈希算法》题集