本文主要是介绍【Leetcode 287】 —— 寻找重复数 |双指针,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
287. 寻找重复数
给定一个包含n + 1
个整数的数组nums
,其数字都在[1, n]
范围内(包括1
和n
),可知至少存在一个重复的整数。
假设nums
只有 一个重复的整数 ,返回 这个重复的数 。
你设计的解决方案必须 不修改 数组nums
且只用常量级O(1)
的额外空间。
示例 1:
输入:nums = [1,3,4,2,2]
输出:2
示例 2:
输入:nums = [3,1,3,4,2]
输出:3
题目分析
算法思路:对 nums 数组建图,每个位置 i 连一条 i→nums[i] 的边。由于存在的重复的数字 target ,因此 target 这个位置一定有起码两条指向它的边,因此整张图一定存在环,且我们要找到的 target 就是这个环的入口,那么整个问题就等价于环路检测/环形链表 II
我们可以使用双指针解决本题,慢指针每次走一步,快指针每次走两步
快指针走了: a + ( b + c ) m + b a + (b+c)m + b a+(b+c)m+b
慢指针走了: a + ( b + c ) n + b a + (b+c)n + b a+(b+c)n+b
根据快走的是慢的两倍,
a + ( b + c ) m + b = 2 ( a + ( b + c ) n + b ) a + (b+c)m + b = 2(a + (b+c)n + b) a+(b+c)m+b=2(a+(b+c)n+b) =>
a = ( b + c ) ( m − 2 n ) − b a = (b+c)(m-2n) - b a=(b+c)(m−2n)−b
得 a 的距离为(环长度的倍数 - b),即从头节点走到环开头节点等于 slow 指针走到环开头节点的距离
双指针顾名思义,就是同时使用两个指针,在序列、链表结构上指向的是位置,在树、图结构中指向的是节点,通过或同向移动,或相向移动来维护、统计信息
经典双指针的数组遍历,更多案例可见 Leetcode 双指针详解
class Solution {public int findDuplicate(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;}
}
这篇关于【Leetcode 287】 —— 寻找重复数 |双指针的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!