news 2026/9/6 21:29:23

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/9/5 19:38:36

使用Jsoup爬取网页中的新闻与图片链接

使用 Jsoup 爬取网页中的新闻与图片链接 在信息聚合、内容监控和数据挖掘的日常开发中&#xff0c;如何从结构化的网页中高效提取图文内容&#xff0c;是许多 Java 工程师面临的实际问题。Jsoup 作为一款轻量级且功能强大的 HTML 解析库&#xff0c;凭借其类 jQuery 的选择器语…

作者头像 李华
网站建设 2026/9/2 22:56:10

PPAP流程详解及提交等级解析

VibeVoice-WEB-UI 技术详解及多说话人语音生成能力解析 在播客制作、有声书演绎或AI角色对话开发中&#xff0c;你是否曾遇到这样的困扰&#xff1a;传统语音合成听起来像“念稿”&#xff0c;角色切换生硬&#xff0c;长段落里音色漂移、情绪断裂&#xff1f;更别提三人以上对…

作者头像 李华
网站建设 2026/9/6 0:33:28

RTK基站设置与GNSS测量操作全解析

RTK基站设置与GNSS测量操作全解析 在城市道路改扩建项目中&#xff0c;测绘团队常面临一个棘手问题&#xff1a;明明设备标称精度达到厘米级&#xff0c;实测成果却频频超限。一位资深工程师发现&#xff0c;问题根源并非仪器性能不足&#xff0c;而是基站架设不当与坐标转换流…

作者头像 李华
网站建设 2026/8/29 8:48:28

大学英语2模拟试卷(一) 题目解析与练习

大学英语2模拟试卷(一) 题目解析与练习 在准备大学英语考试的过程中&#xff0c;许多学生常常陷入一个误区&#xff1a;把语法当作孤立的知识点来死记硬背。然而&#xff0c;真正的语言能力并不只是“知道规则”&#xff0c;而是能在具体语境中准确判断哪个选项最自然、最符合逻…

作者头像 李华
网站建设 2026/9/3 10:27:39

RTK基站设置与测量放样操作全解析

RTK基站设置与测量放样操作全解析 在现代工程测绘中&#xff0c;厘米级精度早已不再是遥不可及的目标。无论是道路施工的桩位放样、电力塔基的精准定位&#xff0c;还是地质灾害监测中的微小位移捕捉&#xff0c;RTK&#xff08;Real-Time Kinematic&#xff09;技术正以前所未…

作者头像 李华
网站建设 2026/8/29 8:48:23

Open-AutoGLM 能在苹果芯片上运行吗:M1/M2/M3全系列实测数据揭晓

第一章&#xff1a;Open-AutoGLM 支持苹果吗Open-AutoGLM 作为一款基于 AutoGLM 架构的开源项目&#xff0c;其对苹果生态系统的兼容性受到广泛关注。随着苹果芯片&#xff08;Apple Silicon&#xff09;在 Mac 设备中的普及&#xff0c;开发者普遍关心该项目是否能在 macOS 系…

作者头像 李华