第287题:寻找重复数

一. 问题描述

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

示例 1:

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

输出: 2

示例 2:

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

输出: 3

说明:

不能更改原数组(假设数组是只读的)。

只能使用额外的 O(1) 的空间。

时间复杂度小于 O(n2) 。

数组中只有一个重复的数字,但它可能不止重复出现一次。

二. 解题思路

本题思路:弗洛伊德循环解法求解。

第一种:弗洛伊德循环解法,通过题目首先,我们可以很容易地证明问题的约束意味着必须存在一个循环。因为 nums 中的每个数字都在 1 和 n 之间,所以它必须指向存在的索引。

对于环的问题,我们可以采用弗洛伊德循环检测方法进行求解。

步骤一:通过数学了解环的入口就是重复数,例如对于数组[2,5,9,6,9,3,8,9,7,1],所得到的环根据第一个数组下标得到某一个数,然后在将这个数当成下标另一个数,如果存在重复数,则肯定有指向那个重复数的多个下标,造成环。

步骤二:证明从开头走到环入口点与相遇后走到环入口点的距离相等,证明在这个网址https://leetcode-cn.com/problems/linked-list-cycle-ii/solution/linked-list-cycle-ii-kuai-man-zhi-zhen-shuang-zhi-/

步骤三:开始设计程序,首先建立快慢指针,fast走两步,low走一步,注意,是根据将数组的值当成下标来进行走,找到相遇点fast==low。

步骤四:然后将fast指向头部,与low接着每次走一步,当相遇时,相遇点就是所求的重复数。

三. 执行结果

执行用时 :0 ms, 在所有 java 提交中击败了100.00%的用户

内存消耗 :37.9 MB, 在所有 java 提交中击败了84.49%的用户

四. Java代码

 public int findDuplicate(int[] nums) {
        int first=nums[0];
        int second=nums[0];
            do{
                second=nums[second];
                second=nums[second];
                first=nums[first];
                        
            }while(second!=first);
            
        second=nums[0];
        while(second!=first) {
            first=nums[first];
            second=nums[second];
        }
            
       return first;
        }

猜你喜欢

转载自www.cnblogs.com/xiaobaidashu/p/12102117.html