標籤:log class output tor 掃描 ram body while迴圈 ted
題目描述在一個長度為n的數組裡的所有數字都在0到n-1的範圍內。 數組中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出數組中任意一個重複的數字。 例如,如果輸入長度為7的數組{2,3,1,0,2,5,3},那麼對應的輸出是第一個重複的數字2。思路:1)直接排序; 2)使用雜湊表,比如開闢一個布爾數組,判斷該數字在之前是否已經訪問過,vector<bool> visit(n,false);已經訪問過,則找到這個重複數字。 3)時間複雜度是O(n),空間複雜度是O(1),這個數組的特點是裡面的元素都是0-n-1之間的數字,如果排好序之後,應該是每個位置上的元素都和下標相等。依次掃描這個數組中的元素,對於下標i對於的元素為m,如果m != i,那麼就將下標為m的元素和下標為i的元素進行交換,直到下標和對應的元素相等為止。理解痛點1:何時退出迴圈,記得numbers[i] != i有可能遇到211,這種根本沒有0的情況,那麼肯定會第二個迴圈陷入死迴圈,這種情況就需要在裡面做出一個if判斷,不應該在while迴圈外面進行if判斷,因為如果是有序的012,numbers[numbers[i]] == numbers[i],那麼找到的就不是想要的結果。理解痛點2:複雜度有兩個for迴圈,但是為什麼時間複雜度是O(n)?攤還分析:每個元素最多交換兩次,所以複雜度是O(n)。
class Solution {public: // Parameters: // numbers: an array of integers // length: the length of array numbers // duplication: (Output) the duplicated number in the array number // Return value: true if the input is valid, and there are some duplications in the array number // otherwise false bool duplicate(int numbers[], int length, int* duplication) { if(length <= 0){ *duplication = -1; return false; } for(int i = 0;i < length;++i){ //必須首先判斷 numbers[i] != i,不然考慮已經排好序的情況,0,1,2,3,4,i= 1,numbers[1] = 1; //肯定numbers[numbers[i]] == numbers[i], while(numbers[i] != i){//可能2,1,1這種沒有0的情況,那麼就會 if(numbers[numbers[i]] == numbers[i]){ *duplication = numbers[i]; return true; } swap(numbers[i],numbers[numbers[i]]); } } *duplication = -1; return false; }};
49 數組中重複的數字 記憶