Leetcode--287. 寻找重复数(Java)
給定一個包含?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) 。
數組中只有一個重復的數字,但它可能不止重復出現一次。
?
思路:
通過數組構建一個循環鏈表,之后通過快慢指針找出循環鏈表環的入口,就是重復的數
例如:題中給出的[1,3,4,2,2],i指向的是nums[i]
所以可以構建循環鏈表:
1-->3
1-->3-->2
1-->3-->2-->4
1-->3-->2-->4-->2
可以看出構建出了一個循環鏈表
因為快指針走兩步,慢指針走一步,每次快比慢多走一步,所以如果有環最后一定可以相遇
?
相遇之后:
我們設定環入口前的長度為a,從環的入口繼續走?b?步到達相遇位置,從相遇位置繼續走?c步回到環的入口
所以環長R=b+c
慢指針走了a+b步
所以快指針走了2*(a+b)步
因為在相遇時快比慢是多走了n圈環
所以也可以說快指針走了a+b+n*L步
所以2*(a+b) =?a+b+n*L
所以a+b=n*L
所以現在讓某一個指針從頭開始走,另一個從環入口開始走,每次都是走一步
因為a+b的距離是環長度的n倍,所以他們一定會在環的 入口相遇。
我們就可以求出這個環的入口。
代碼:
//1-->3-->2-->4-->2class?Solution?{public?int?findDuplicate(int[]?nums)?{int?fast?=?0,?slow?=?0;while(true)?{fast?=?nums[nums[fast]];slow?=?nums[slow];if(slow?==?fast)?{fast?=?0;while(nums[slow]?!=?nums[fast])?{fast?=?nums[fast];slow?=?nums[slow];}return?nums[slow];}}}}?
總結
以上是生活随笔為你收集整理的Leetcode--287. 寻找重复数(Java)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【剑指offer】面试题25:合并两个排
- 下一篇: 牛客网--单词倒排(Java)