news 2026/3/13 2:42:50

LeetCode136/169/75/31/287 算法技巧题核心笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode136/169/75/31/287 算法技巧题核心笔记

目录

一、136. 只出现一次的数字

题目概述

核心理论

解题思路

解法实现(Java)

复杂度分析

重难点分析

同类题拓展

二、169. 多数元素

题目概述

核心理论

解题思路

解法实现(Java)

复杂度分析

重难点分析

同类题拓展

三、75. 颜色分类

题目概述

核心理论

解题思路

解法实现(Java)

复杂度分析

重难点分析

同类题拓展

四、31. 下一个排列

题目概述

核心理论

解题思路

解法实现(Java)

复杂度分析

重难点分析

同类题拓展

五、287. 寻找重复数

题目概述

核心理论

解题思路

解法实现(Java)

复杂度分析

重难点分析


本笔记涵盖 5 道高频算法技巧题的核心解法、理论依据、重难点及拓展,适用于笔试 / 面试复习。

一、136. 只出现一次的数字

题目概述

给定非空整数数组,仅一个元素出现 1 次,其余元素出现 2 次,找出该唯一元素。

核心理论

位运算 异或(^)的三大特性:

  1. 相同数异或为 0:a ^ a = 0
  2. 0 与任意数异或为其本身:0 ^ a = a
  3. 满足交换 / 结合律:a ^ b ^ c = a ^ c ^ b

解题思路

遍历数组,将所有元素依次异或,出现 2 次的元素会相互抵消为 0,最终结果即为 “只出现 1 次的元素”。

解法实现(Java)

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

复杂度分析

  • 时间复杂度:O(n)(遍历数组 1 次)
  • 空间复杂度:O(1)(仅用一个变量)

重难点分析

  • 易错点:容易优先想到 “哈希表统计频率”,但会额外占用O(n)空间,不符合最优解要求。
  • 关键:理解 “异或抵消重复元素” 的本质,避免冗余空间开销。

同类题拓展

  • 只出现一次的数字 II(其余元素出现 3 次)
  • 只出现一次的数字 III(有 2 个元素各出现 1 次)

二、169. 多数元素

题目概述

给定整数数组,找出出现次数 ** 大于n/2** 的元素(多数元素)。

核心理论

  1. 摩尔投票法:多数元素的出现次数超过其他所有元素之和,可通过 “抵消” 筛选候选元素。
  2. 排序特性:排序后数组的中间元素(索引n/2)必然是多数元素。

解题思路

摩尔投票法

  1. 初始化 “候选元素” 和 “计数”。
  2. 遍历数组:遇相同元素则计数 + 1,不同则 - 1;计数为 0 时更换候选元素。
  3. 最终候选元素即为多数元素。

解法实现(Java)

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

复杂度分析

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

重难点分析

  • 易错点:摩尔投票法中 “计数为 0 时更换候选” 的逻辑容易遗漏,导致候选元素错误。
  • 关键:理解 “多数元素必然能抵消所有非多数元素” 的核心逻辑,无需统计具体次数。

同类题拓展

  • 求众数 II(找出出现次数超过n/3的元素)

三、75. 颜色分类

题目概述

给定包含0、1、2的数组(代表红、白、蓝),原地排序0→1→2的顺序,禁止使用库排序函数。

核心理论

三指针法(荷兰国旗问题):用 3 个指针划分 3 个区域(0 的区域、1 的区域、2 的区域),一次遍历完成排序。

解题思路

  1. 定义指针:
    • left:0 的右边界(下一个 0 的位置)
    • right:2 的左边界(下一个 2 的位置)
    • i:当前遍历指针
  2. 遍历逻辑:
    • 遇 0:与left交换,left++i++
    • 遇 2:与right交换,right--i不移动,需检查交换后的元素)
    • 遇 1:直接i++

解法实现(Java)

class Solution { public void sortColors(int[] nums) { int left = 0, right = nums.length - 1, i = 0; while (i <= right) { if (nums[i] == 0) { swap(nums, i++, left++); } else if (nums[i] == 2) { swap(nums, i, right--); } else { i++; } } } private void swap(int[] nums, int a, int b) { int temp = nums[a]; nums[a] = nums[b]; nums[b] = temp; } }

复杂度分析

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

重难点分析

  • 易错点:交换 2 时,i容易误加 1,导致未检查交换后的元素(可能是 0)。
  • 关键:明确三指针的 “区域划分” 作用,避免指针移动逻辑混乱。

同类题拓展

  • 移动零(将 0 移到数组末尾)
  • 合并两个有序数组(双指针原地合并)

四、31. 下一个排列

题目概述

找出数组的下一个字典序更大的排列;若不存在,则重排为升序(最小排列),要求原地修改、常数空间。

核心理论

字典序 “最小增幅” 规律:

  1. 升序断点:从后往前找第一个nums[i] < nums[i+1]的索引ii可增大)。
  2. 最小增幅数:从后往前找第一个nums[j] > nums[i]的索引j(保证增幅最小)。
  3. 调整后续顺序:交换i、j后,反转i+1后的元素(将降序转为升序,保证后续最小)。

解题思路

  1. 找升序断点i:若未找到(数组降序),直接反转数组。
  2. 若找到i,找j并交换nums[i]、nums[j]
  3. 反转i+1到末尾的元素。

解法实现(Java)

class Solution { public void nextPermutation(int[] nums) { int n = nums.length, i = n - 2; // 步骤1:找升序断点 while (i >= 0 && nums[i] >= nums[i+1]) i--; // 步骤2:找j并交换 if (i >= 0) { int j = n - 1; while (nums[j] <= nums[i]) j--; swap(nums, i, j); } // 步骤3:反转后续元素 reverse(nums, i+1, n-1); } private void swap(int[] nums, int a, int b) { int temp = nums[a]; nums[a] = nums[b]; nums[b] = temp; } private void reverse(int[] nums, int l, int r) { while (l < r) swap(nums, l++, r--); } }

复杂度分析

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

重难点分析

  • 易错点:遗漏 “数组完全降序” 的情况(未找到i时,需反转整个数组)。
  • 关键:理解 “最小增幅” 的核心 —— 既让排列变大,又只变大 “一点点”。

同类题拓展

  • 全排列(生成所有字典序排列)
  • 第 k 个排列(找到第 k 个字典序排列)

五、287. 寻找重复数

题目概述

给定长度为n+1的数组(元素范围[1,n]),有且仅一个重复数,要求不修改数组、常数空间找出该数。

核心理论

快慢指针(弗洛伊德环检测):将数组转化为 “链表”(索引 = 节点,值 = 下一个节点索引),重复数是环的入口(重复数对应多个前驱节点)。

解题思路

  1. 找相遇点:慢指针slow走 1 步,快指针fast走 2 步,两者在环内相遇。
  2. 找环入口:新指针ptr从起点出发,slow从相遇点出发,两者同速前进,最终在环入口(重复数)相遇。

解法实现(Java)

class Solution { public int findDuplicate(int[] nums) { // 步骤1:找快慢指针相遇点 int slow = nums[0], fast = nums[nums[0]]; while (slow != fast) { slow = nums[slow]; fast = nums[nums[fast]]; } // 步骤2:找环入口(重复数) int ptr = 0; while (ptr != slow) { ptr = nums[ptr]; slow = nums[slow]; } return ptr; } }

复杂度分析

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

重难点分析

  • 易错点:难以想到 “数组转链表” 的思路,或不理解 “ptr 与 slow 相遇于环入口” 的数学逻辑。
  • 关键:记住结论:从起点和相遇点出发的同速指针,必然在环入口相遇

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/11 17:57:00

欧姆龙SCU42模块串口通信配置与应用

欧姆龙SCU42模块串口通信配置与应用 在现代自动化控制系统中&#xff0c;PLC 与各类外围设备的可靠通信是实现数据采集和远程控制的关键。面对变频器、温控仪、HMI 等多种异构设备并存的现场环境&#xff0c;如何高效地构建稳定的数据链路&#xff1f;欧姆龙 CJ1W-SCU42 串行通…

作者头像 李华
网站建设 2026/3/11 5:18:45

从有道云笔记迁移前端学习笔记至CSDN

从有道云笔记迁移前端学习笔记至CSDN 在整理旧技术笔记时&#xff0c;偶然发现了一个有趣的问题&#xff1a;我们花了大量时间写下的知识&#xff0c;最终却只能“沉睡”在私人笔记软件里。比如我用了多年的有道云笔记&#xff0c;里面堆满了前端学习记录、API 对比、样式技巧…

作者头像 李华
网站建设 2026/3/10 15:09:43

图形旋转与翻折典型题型解析

图形旋转与翻折典型题型解析 在中学几何的解题战场上&#xff0c;图形的旋转与翻折是高频出现的核心变换手段。它们不仅仅是视觉上的移动&#xff0c;更是隐藏着深刻数学结构的“密码”。掌握这些变换背后的不变性——如长度守恒、角度相等、对称关系——往往能打开复杂问题的突…

作者头像 李华
网站建设 2026/3/11 20:39:08

Windows Server 2012 R2 AD域中DHCP配置详解

Windows Server 2012 R2 AD域中DHCP配置实战指南 在现代企业网络中&#xff0c;IP地址管理看似基础&#xff0c;实则影响深远。一个未经规划的DHCP部署&#xff0c;轻则导致客户端频繁掉线、解析失败&#xff0c;重则引发IP冲突、非法服务器泛滥&#xff0c;甚至成为安全渗透的…

作者头像 李华
网站建设 2026/3/10 4:21:05

Pandas与R语言数据处理120题实战

Pandas与R语言数据处理120题实战 还在为找不到贴合人设的配音发愁&#xff1f;试试 B 站开源的 IndexTTS 2.0&#xff01;这款自回归零样本语音合成模型&#xff0c;支持上传人物音频与文字内容&#xff0c;一键生成匹配声线特点的音频&#xff0c;轻松搞定各类配音需求。 基础…

作者头像 李华
网站建设 2026/3/12 18:52:32

欧姆龙SCU模块实现Modbus RTU与无协议通信

欧姆龙SCU模块实现Modbus RTU与无协议通信 在现代工业自动化系统中&#xff0c;PLC 与各类智能设备的串行通信需求日益复杂。尤其是在需要同时对接多种第三方设备&#xff08;如变频器、温控仪、仪表等&#xff09;的场景下&#xff0c;传统的标准协议往往难以满足灵活集成的需…

作者头像 李华