1. 程式人生 > >【Leetcode】287. Find the Duplicate Number(快慢指標+連結串列找環的起點)

【Leetcode】287. Find the Duplicate Number(快慢指標+連結串列找環的起點)

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

Example 1:
Input: [1,3,4,2,2]
Output: 2

Example 2:
Input: [3,1,3,4,2]
Output: 3

Note:
You must not modify the array (assume the array is read only).
You must use only constant, O(1) extra space.
Your runtime complexity should be less than O(n2n^2).
There is only one duplicate number in the array, but it could be repeated more than once.

題目大意

給你一個數組,這個陣列中只有一個重複的數字,讓你找出陣列中重複的數字。其中 1

ainums.size()1\le a_i\le nums.size()
限制條件:

  1. 只能使用 O(1) 的空間,
  2. 不能改變原有陣列
  3. 複雜度小於 O(n2n^2)

解題思路

由於題目中很多的限制,所以直接排序然後判斷相鄰元素是不是相等這個演算法就不可以使用了,其實這裡有一個複雜度為 O(nlog(n))O(nlog(n)) 的,就是藉助二分答案然後判斷,具體不展開說了,主要說一下快慢指標的使用。
因為給定的陣列元素 1ainums.size()1\le a_i\le nums.size(),那麼我們做一個關於下標和陣列元素值對映,那麼這個對映不是一對一的,是一個多對一的對映,比如說有一個數組 【1, 2, 4, 1, 3】,那麼做一個對映【{0,3}->1,1->2,2->4,4->3】,然後我們去遍歷,遍歷的規則是 x

=nums[x]x=nums[x],那麼就有一個遍歷序列為 {0,1,2,4,3,1}\{0,1,2,4,3,1\},顯然這是一個環,那麼我們要找的其實就是這個環的起點,那麼我們設定兩個指標,一個快指標fast,每次走兩步;一個慢指標slow,每次走一步,那麼肯定會在某個點相遇,這時我們將快指標fast 置為 00,然後每次走一步,直到兩個指標相遇結束,這時相遇點就是環的起點,也是我們所求的重複的數,複雜度 O(n)O(n)

證明

證明1:為什麼快慢指標在第一次一定會相遇。

1)  當快指標比慢指標慢 11 個單位的時候,那麼這時候快指標走兩步,慢指標走一步,正好相遇。
2)  當快指標比慢指標慢 22 個單位的時候,那麼這時候快指標走兩步,慢指標走一步,回到條件1)
n)  當快指標比慢指標慢 nn 個單位的時候,那麼這時候快指標走兩步,慢指標走一步,回到條件n-1)
那麼根據數學歸納法,快慢指標一定會相遇。

證明2:為什麼快慢指標在第一次相遇時,把快指標置為0之後,在第二次相遇時就是環的起點。

請看下圖:
在這裡插入圖片描述

因為有 a=ca=c,所以將快指標置為 00,每次走一步,那麼下次快慢指標相遇的時候就是環的起點,也就是我們所求重複數的值。

程式碼如下

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int slow = nums[0];
        int fast = nums[slow];
        while(slow != fast) {
            slow = nums[slow];
            fast = nums[nums[fast]];
        }
        fast = 0;
        while(slow != fast) {
            slow = nums[slow];
            fast = nums[fast];
        }
        return slow;
    }
};

相關推薦

Leetcode287. Find the Duplicate Number快慢指標+連結串列起點

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate

LeetCode287. Find the Duplicate Number

287. Find the Duplicate Number Description: Given an array nums containing n + 1 integers where each integer is between 1 and n (in

LeetCode287. Find the Duplicate Number出重複的數

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one

LeetCode 287. Find the Duplicate Number 找到重復的數字

ant pre ast web integer lan algorithm xtra 理論 Given an array nums containing n + 1 integers where each integer is between 1 and n (inclus

leetcode 287. Find the Duplicate Number二分/快慢指標

1.二分方法 因為數字是1~n,所以我們可以根據小於mid的數目來判斷重複的數字是在左邊還是右邊 class Solution { public: int findDuplicate(vector<int>& nums) { int lef

LeetCode & 劍指offer刷題陣列題5:3 陣列中重複的數字287. Find the Duplicate Number

【LeetCode & 劍指offer 刷題筆記】目錄(持續更新中...) 287 .   Find the Duplicate Number Given an array   nums

LeetCode 287. Find the Duplicate Number

find 由於 ray all turn num pre n-1 DDU 解法一: 類似 LeetCode 442. Find All Duplicates in an Array,由於元素是1~n,因此每個元素的值-1(映射到0~n-1)就可以直接當做下標。 cl

[LeetCode] 287. Find the Duplicate Number 尋找重復數

blank arc modify ini lba read href use rep Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive

leetcode 217. Contains Duplicate 287. Find the Duplicate Number

DDU dup detail The .html cto false urn .net 217. Contains Duplicate 後面3個題都是限制在1~n的 class Solution { public: bool containsDuplicate(

[LeetCode] 287. Find the Duplicate Number

etc int 一個數 空間 ont slow i++ for clu Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prov

[leetcode]287. Find the Duplicate Number

[leetcode]287. Find the Duplicate Number Analysis fighting!!!—— [每天刷題並不難0.0] Given an array nums containing n + 1 integers where e

LeetCode 287 Find the Duplicate Number

287. Find the Duplicate Number Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove tha

python leetcode 287. Find the Duplicate Number

class Solution: def findDuplicate(self, nums): """ :type nums: List[int] :rtype: int """ for i in rang

LeetCode---287. Find the Duplicate Number

題目 給出一個含有n+1個元素的陣列,裡面的元素值在1到n的範圍內,找出重複的數字,假設只存在一個重複的數字,該數字的次數可能出現多次。 Python題解 class Solution:

leetcode 287 Find the Duplicate Number尋找重復數

bre i++ The () stl容器 insert cat != bsp 這道題用STL容器就很好寫了,可以用set也可以用map, 用unordered_map的C++代碼如下: 1 class Solution { 2 public: 3 int

287. Find the Duplicate Number

you 原理 mat 行動 row dup pac dex strong Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), pro

287. Find the Duplicate Number 尋找重複數

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate element

LeetCode從零單刷Find the Duplicate Number

題目: Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive)

LeetCode 287.尋找重複數 Find the Duplicate Number

題目連結 一個長度是n+1的陣列,出現的整數都在1到n之間(包括1和n),已知有一個重複出現的整數。求該整數。 要求: 1.不能更改原陣列 2.空間複雜度O(1) 3.時間複雜度小於O(n²) 4.陣列中只有一個重複的數字,但它可能不止重複出現1次。

LeetCode-Find the Duplicate Number

一、Description 題目描述: 給定n + 1個數字,這些數字的範圍在1 - n之間,在這些數字中有一個出現不止一次的數字,找出這個數字。 要求用O(1)的空間和少於O(n^2)的時間複雜度。 二、Analyzation 遍歷這個陣列,對於每個數字x,nums[x