携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第31天,点击查看活动详情
前言
- leetcode hot100,是大厂面试高频题,也是必刷算法题。精选了100道LeetCode上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,按照官方说的,熟练掌握这 100 道题,就具备了代码世界通行的基本能力。
leetcode287题(# 寻找重复数)
本文来讲hot100第287题(寻找重复数),本题有三种解法,二进制、二分查找、快慢指针,我们本篇文章使用快慢指针来讲。
给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。
假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。
你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。
示例:
输入: nums = [1,3,4,2,2]
输出: 2
输入: nums = [3,1,3,4,2]
输出: 3
提示:
1 <= n <= 105nums.length == n + 11 <= nums[i] <= nnums中 只有一个整数 出现 两次或多次 ,其余整数均只出现 一次
进阶:
- 如何证明
nums中至少存在一个重复的数字? - 你可以设计一个线性级时间复杂度
O(n)的解决方案吗?
分析
- 数组的数组范围为[1, n]
- 数组存在一个重复的整数,可能出现多次
- 要求不修改数组nums切使用O(1)的额外空间
思路
- 我们可以使用快慢指针来解决,与141/142题环形列表的题目方法一样。
- 由于存在重复的数字,那么目标至少数字有2个指向它的边,那么整个数组一定会形成一个环
- 所以我们要找到的环的入口,找到了入口也就找到了重复的数字
- 设一个慢指针,一个快指针,慢指针每次走一步,快指针每次走二步,
- 当2个指针相遇,我们再将慢指针放到起点0,2个指针每次同时移动一步,相遇的点就是答案
代码
let 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(n),空间复杂度O(1)