LeetCode 287.尋找重複數 Find the Duplicate Number
阿新 • • 發佈:2018-12-11
一個長度是n+1的陣列,出現的整數都在1到n之間(包括1和n),已知有一個重複出現的整數。求該整數。
要求:
1.不能更改原陣列
2.空間複雜度O(1)
3.時間複雜度小於O(n²)
4.陣列中只有一個重複的數字,但它可能不止重複出現1次。
花了點時間才想明白,原來二分法可以這麼使用。
當n為奇數,且重複出現的數字為奇數,奇數個數>偶數個數
當n為奇數,且重複出現的數字為偶數,偶數個數>=奇數個數
當n為偶數,且重複出現的數字為奇數,奇數個數>偶數個數
當n為偶數,且重複出現的數字為偶數,偶數個數>奇數個數
總結一下就是:
當奇數個數>偶數個數時,重複出現的數字在奇數裡,那麼繼續從奇數的奇數和奇數的偶數裡找。
當偶數個數>=奇數個數時,重複出現的數字在偶數裡,那麼繼續從偶數的奇數和偶數的偶數裡找。
什麼時候算是找到了呢,
當奇數個數==0,說明偶數裡全是重複的數字(對嗎,欸,是嗎)
當偶數個數==0,說明奇數裡全是重複的數字
程式碼如下:
class Solution { public: int findDuplicate(vector<int>& nums) { int len=nums.size(); int s1=1,s2=2,d=2,couts1,couts2;//糟糕的命名,s1表示奇,s2表示偶, int s_1,s_2; while(1) { couts1=0; couts2=0; s_1=s1%d; s_2=s2%d; for(int i=0;i<len;i++) { if(nums[i]%d==s_1) couts1++; if(nums[i]%d==s_2) couts2++; } if(couts1==0) { for(int i=0;i<len;i++) { if(nums[i]%d==s_2) return nums[i]; } } if(couts2==0) { for(int i=0;i<len;i++) { if(nums[i]%d==s_1) return nums[i]; } } if(couts1>couts2) { s1=s1; s2=s1+d; } else { s1=s2; s2=s2+d; } d*=2; } } };