Skip to content

Latest commit

 

History

History
80 lines (68 loc) · 2.06 KB

File metadata and controls

80 lines (68 loc) · 2.06 KB

题目描述:给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。

eg:

示例 1:

输入: [1,3,4,2,2]
输出: 2
示例 2:

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

思路描述:最简单的方法就是先排序再遍历

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        for(int i = 1; i < nums.size(); i ++){
            if(nums[i] == nums[i - 1])
                return nums[i];
        }
        return 0;
    }
};

然后还可以使用面试题03中的策略,但是还是会对数组进行修改

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        for(int i = 0; i < nums.size(); i ++){
            while(i != nums[i]){
                if(nums[i] == nums[nums[i]])
                    return nums[i];
                swap(nums[i], nums[nums[i]]);
            }
        }
        return -1;
    }
};

弗洛伊德龟兔赛跑算法:

如果我们对 nums 进行这样的解释,即对于每对索引 $i$ 和值 $v_i$ 而言,“下一个” $v_j$ 位于索引 $v_i$ 处,我们可以将此问题减少到循环检测。

首先,我们可以很容易地证明问题的约束意味着必须存在一个循环。因为 $nums$ 中的每个数字在 1 和 n之间,所以它必须指向存在的索引,此外,由于 0 不能作为 nums中的值出现,nums[0] 不能作为循环的一部分。

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int tortoise = nums[0];
        int hare = nums[0];
        do {
            tortoise = nums[tortoise];
            hare = nums[nums[hare]];
        } while (tortoise != hare);
        
        // Find the "entrance" to the cycle.
        int ptr1 = nums[0];
        int ptr2 = tortoise;
        while (ptr1 != ptr2) {
            ptr1 = nums[ptr1];
            ptr2 = nums[ptr2];
        }
        return ptr1;
    }
};