🧩Algo 技巧

287. 寻找重复数

难度:🟡 Medium | 标签:快慢指针、Floyd 找环 | 状态:⬜ LeetCode 链接

思路

数组下标 [0, n],值 [1, n]。把 i → nums[i] 视为链表,有重复 ⇔ 有环。 Floyd 找环入口法:

  1. 快慢指针在环内相遇
  2. 一指针从 0,一指针从相遇点,同速走,再次相遇即环入口(即重复值)

代码

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int slow = nums[0], 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)

易错 / 回顾

  • 不能改数组(题目要求)→ 不能排序也不能标记
  • O(1) 空间 → 不能哈希
  • 二分解法 O(n log n):枚举答案 m,统计 <= m 的个数
Related · 技巧