寻找重复数 - LeetCode 287 题解笔记

devtools/2025/3/29 19:32:27/

寻找重复数 - LeetCode 287 题解笔记

问题描述

给定一个包含 n + 1 个整数的数组 nums,其数字都在 [1, n] 范围内(包括 1 和 n),已知至少存在一个重复的整数。假设 nums 只有一个重复的整数,返回这个重复的数。

要求

  • 不修改数组 nums
  • 只使用常量级 O(1) 的额外空间

解题思路

方法一:快慢指针法(Floyd判圈算法

核心思想

将数组视为链表,利用快慢指针检测环的存在并找到环的入口:

  1. 数组映射为链表

    • 索引作为节点
    • 数组值作为指向下一个节点的指针
  2. 重复数字必然形成环

    • 因为多个索引指向同一个值
    • 例如 nums = [1,3,4,2,2] → 0→1→3→2→4→2→4→…(在2和4之间形成环)
算法步骤
  1. 第一阶段:检测环

    • 快指针每次走两步,慢指针每次走一步
    • 当两者相遇时,确认存在环
  2. 第二阶段:找到环入口

    • 将慢指针重置到起点
    • 快慢指针改为每次各走一步
    • 再次相遇点即为重复数字
class Solution {public int findDuplicate(int[] nums) {// 初始都从第一个元素开始int slow = nums[0];int fast = nums[0];// 第一阶段:找到相遇点do {slow = nums[slow];fast = nums[nums[fast]];} while (slow != fast);// 第二阶段:找到环的入口slow = nums[0];while (slow != fast) {slow = nums[slow];fast = nums[fast];  // 这里应该是单步移动,不是双步}return slow;}
}
复杂度分析
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

方法二:二分查找法

核心思想

利用抽屉原理进行二分查找:

  1. 数值范围二分

    • 在[1,n]范围内二分
    • 统计小于等于mid的数的个数
  2. 调整搜索范围

    • 如果计数 > mid,说明重复数在左半区
    • 否则在右半区
class Solution {
public:int findDuplicate(vector<int>& nums) {int n = nums.size();int l = 1, r = n - 1, ans = -1;while (l <= r) {int mid = (l + r) >> 1;int cnt = 0;for (int i = 0; i < n; ++i) {cnt += nums[i] <= mid;}if (cnt <= mid) {l = mid + 1;} else {r = mid - 1;ans = mid;}}return ans;}
};
复杂度分析
  • 时间复杂度:O(n log n)
  • 空间复杂度:O(1)

关键点说明

  1. 为什么快慢指针能工作

    • 重复数字导致多个节点指向同一个节点
    • 形成环后,快指针最终会追上慢指针
  2. 边界条件处理

    • 数组长度至少为2(因n≥1)
    • 保证只有一个重复数字
  3. 与常规链表环检测的区别

    • 不需要实际构建链表
    • 直接利用数组索引和值的映射关系

http://www.ppmy.cn/devtools/171436.html

相关文章

批量启动远程服务

在ZooKeeper集群中&#xff0c;需要启动所有服务节点&#xff08;至少达到法定人数&#xff09;才能保证集群正常对外提供服务&#xff0c;一下是批量启动服务的脚本 编写启动脚本 vim start_servers.sh #判断参数个数 if [ $# -lt 1 ]; thenecho "错误&#xff1a;请输…

卷积神经网络的原理、实现及变体

卷积神经网络convolutional neural network&#xff0c;CNN 是为处理图像数据而生的网络&#xff0c;主要由卷积层&#xff08;填充和步幅&#xff09;、池化层&#xff08;汇聚层&#xff09;、全连接层组成。 卷积 虽然卷积层得名于卷积&#xff08;convolution&#xff09…

补充--HTTP常见的状态码

1xx&#xff08;信息性状态码&#xff09; - 表示接收的进程正在请求中&#xff0c;客户端应继续其操作。 100 Continue&#xff08;继续&#xff09;: 客户端应该继续其请求。 101 Switching Protocols&#xff08;切换协议&#xff09;: 服务器根据客户端的请求切换协议。 …

尝试使用Tauri2+Django+React项目(2)

前言 尝试使用tauri2DjangoReact的项目-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146403103在前面笔者不知道怎么做&#xff0c;搞了半天 笔者看到官网&#xff0c;原来可以使用二进制文件&#xff0c;好好好 嵌入外部二进制文件 | Taurihttps://v2.taur…

解析DeepSeek的技术内核:混合专家架构如何重塑AI效能

解析DeepSeek的技术内核&#xff1a;混合专家架构如何重塑AI效能 在当今大型语言模型&#xff08;LLM&#xff09;竞争激烈的赛道上&#xff0c;中国AI企业DeepSeek凭借其独特的技术路线脱颖而出。其核心优势之一&#xff0c;便是对混合专家&#xff08;Mixture of Experts&…

A2 最佳学习方法

记录自己想法的最好理由是发现自己的想法&#xff0c;并将其组织成可传播的形式 (The best reason for recording what one thinks is to discover what one thinks and to organize it in transmittable form.) Prof Ackoff 经验之谈&#xff1a; 做培训或者写文章&#xff…

精通服务器推送事件(SSE)与 Python 和 Go 实现实时数据流 [特殊字符]

在当今的互动型 Web 应用程序中&#xff0c;实时数据更新在提升用户体验方面起着至关重要的作用。无论是实时股票更新、即时聊天消息&#xff0c;还是流式评论&#xff0c;实时数据流都是不可或缺的。在各种可用于实时通信的技术中&#xff0c;服务器推送事件&#xff08;SSE&a…

2025前端面试题记录

vue项目目录的执行顺序是怎么样的&#xff1f; 1、package.json   在执行npm run dev时&#xff0c;会在当前目录寻找package.json文件&#xff0c;此文件包含了项目的名称版本、项目依赖等相关信息。 2、webpack.config.js(会被vue-cli脚手架隐藏) 3、vue.config.js   对…