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

LeetCode 287:快慢指针巧解重复数

LeetCode287

给定一个包含n + 1个整数的数组nums,其数字都在[1, n]范围内(包括1n),可知至少存在一个重复的整数。

假设nums只有一个重复的整数,返回这个重复的数

你设计的解决方案必须不修改数组nums且只用常量级O(1)的额外空间。

示例 1:

输入:nums = [1,3,4,2,2],输出:2

示例 2:

输入:nums = [3,1,3,4,2],输出:3

示例 3 :

输入:nums = [3,3,3,3,3],输出:3

Python解法

1.二分查找

class Solution: def findDuplicate(self, nums: List[int]) -> int: left = 1 right = len(nums) - 1 while left < right: mid = (left + right) // 2 cnt = 0 for num in nums: if num <= mid: cnt += 1 if cnt > mid: right = mid else: left = mid + 1 return left

2.快慢指针

class Solution: def findDuplicate(self, nums: List[int]) -> int: slow = fast = 0 # 第一阶段:快慢指针不同速,环内相遇 while True: slow = nums[slow] fast = nums[nums[fast]] if slow == fast: break # 第二阶段:slow重置起点,同速找环入口 slow = 0 while slow != fast: slow = nums[slow] fast = nums[fast] return slow

Java解法

1.二分查找

class Solution { public int findDuplicate(int[] nums) { int left = 1; int right = nums.length - 1; int mid = 0; int cnt = 0; while(left < right){ mid = (left + right) / 2; cnt = 0; for(int num : nums){ if(num <= mid){ cnt++; } } if(cnt > mid){ right = mid; }else{ left = mid + 1; } } return left; } }

2.快慢指针

public int findDuplicate(int[] nums) { int slow = 0, fast = 0; // 1.快慢指针不同速,直到环内相遇 do { slow = nums[slow]; // 走1步 fast = nums[nums[fast]]; // 走2步 } while (slow != fast); // 2.慢指针放回起点,二者同速前进 slow = 0; while (slow != fast) { slow = nums[slow]; fast = nums[fast]; } return slow; }

C++解法

1.二分查找

class Solution { public: int findDuplicate(vector<int>& nums) { int left = 1; int right = nums.size() - 1; int mid = 0; int cnt = 0; while(left < right){ mid = (left + right) / 2; cnt = 0; for(int num : nums){ if(num <= mid){ cnt++; } } if(cnt > mid){ right = mid; }else{ left = mid + 1; } } return left; } };

2.快慢指针

#include <vector> using namespace std; class Solution { public: int findDuplicate(vector<int>& nums) { int slow = 0, fast = 0; // 第一步:快慢指针相遇 do { slow = nums[slow]; fast = nums[nums[fast]]; } while (slow != fast); // 第二步:同速前进找入口 slow = 0; while (slow != fast) { slow = nums[slow]; fast = nums[fast]; } return slow; } };

快慢指针

快慢指针核心优势:仅 O (1) 额外空间,一次 / 两次遍历完成,无需额外容器,分为「快慢步速差指针」「前后同步快慢指针」两大类。

场景 1:链表判环、找环入口(Floyd 龟兔算法)

适用题目

  • LeetCode141 环形链表(判断链表是否存在环)
  • LeetCode142 环形链表 II(找到环的起始节点)
  • LeetCode287 寻找重复数(数组映射为带环链表)

思路:快指针一次走 2 步,慢指针一次 1 步,有环必相遇;再同速找入口。

场景 2:链表 / 数组找中点、倒数第 k 个节点

1)找链表中点(LeetCode876 链表的中间结点)

slow 走 1 步,fast 走 2 步;fast 走到末尾时,slow 刚好在中点。

2)倒数第 k 个节点(LeetCode19 删除链表倒数第 N 个结点)

快指针先提前走 k 步,再快慢同速向后走;fast 到末尾时 slow 指向倒数第 k 个。

场景 3:原地数组分区、移动元素(如 LeetCode283 移动零)

slow 记录下一个合法元素存放位置,fast 遍历数组;fast 找到符合条件元素时,和 slow 交换 / 覆盖,slow 前进。 类似题目:移除元素、颜色分类。

场景 4:链表判回文(LeetCode234)

快慢指针找到链表中点,反转后半段,再前后指针同步比对。

场景 5:链表奇偶重排、拆分链表

用快慢指针分割链表为前后两部分,再重组。

场景 6:滑动窗口类优化(快慢指针 / 滑动窗口双指针)

slow 为窗口左边界,fast 为右边界,满足条件收缩左边界;常用于子数组求和、最长无重复子串等。

局限

  1. 仅适用于线性结构(链表、可映射为链表的数组);
  2. 环形问题需要数学推导理解,逻辑门槛高于二分、哈希;
  3. 无法处理多环、多入口复杂结构(仅单环单入口场景)。
http://www.jsqmd.com/news/1171694/

相关文章:

  • MCTS 自动驾驶规划实战:泊车场景 3 步构建代价函数与 UCB 调优
  • ADS1015L与MKV44F64VLH16构建精密ADC系统指南
  • STM32F1 HAL库300题 — 交互式习题库
  • 基于SpringBoot的摄影预约管理系统(Java+SpringBoot+MySQL)| 计算机毕业设计 附源码论文PPT
  • 彻底解决 Python 报错:ModuleNotFoundError: No module named ‘xxx‘ 终极指南
  • VSCode Git 与终端协同:5个高效命令替代图形化操作
  • DeepSeek-VL2稀疏MoE多模态模型:高效视觉语言理解实践指南
  • OpenAI Python实战避坑指南:RAG、流式响应与函数调用5大生产级能力
  • VS Code Markdown 插件组合:3款核心工具配置与10个快捷键效率提升
  • NOKOV动捕系统室外部署避坑指南:3大环境干扰源排查与镜头选型建议
  • 2026抚顺漏水检测维修口碑榜TOP5权威推荐:正规防水补漏公司甄选-卫生间/厨房/阳台/屋顶/地下室渗漏水精准查漏:房屋防水补漏避坑指南 - 安佳防水
  • Unity Shader变体优化实战:从原理到应用,解决包体与性能难题
  • J-Link 驱动 V8.50 与 Keil 5.36 版本冲突:2种排查方法与修复方案
  • UE5视频播放黑屏问题:切换ElectraPlay解码器彻底解决MP4兼容性
  • C程序ANSI彩色日志实践
  • 大模型轻量化实战:任务分解与智能调度架构解析
  • ArcGIS Online 与 Pro 协同制图:3种高效流程实现科研数据可视化与共享
  • 多维聚合:从SQL GROUP BY到交互式数据立方体的工程实践
  • NBM7100A与PIC18LF45K50实现纽扣电池寿命优化方案
  • Hadoop YARN UI 2.0 配置实战:Apache 3.3.5 集群启用新界面 3 步指南
  • Python条件判断、用户输入与循环的协同设计原理
  • 2026年7月最新扬州芝柏官方售后客户服务热线与维修网点地址汇总 - 亨得利官方服务中心
  • 2026年7月最新大连雅典官方售后客服服务电话及地址网点大全 - 亨得利官方服务中心
  • ROS2 C++节点内嵌rosbag2写入:SequentialWriter实战指南
  • 专利侵权诉讼机构
  • AI安全技术博文创作的合规性与内容可行性标准
  • ZooKeeper 3.6.3 集群部署:3节点配置与防火墙端口 2181/2888/3888 详解
  • L3交换机VLAN间路由配置:3步实现子网隔离与互通(附思科/华为命令)
  • 2026年7月最新厦门格拉苏蒂官方售后服务热线与网点地址查询 - 亨得利钟表维修中心
  • C++与OpenCV实现工业视觉卡尺工具:亚像素直线边缘检测与测量