Acwing 14 不修改陣列找出重複的數字
阿新 • • 發佈:2020-08-05
給定一個長度為 \(n+1\) 的陣列 \(nums\),陣列中所有的數均在 \(1∼n\) 的範圍內,其中 \(n≥1\)。
請找出陣列中任意一個重複的數,但不能修改輸入的陣列。
樣例:給定 nums = [2, 3, 5, 4, 3, 2, 6, 7]。
返回 2 或 3。
本題利用抽屜原理:n+1 個蘋果放在 n 個抽屜裡,那麼至少有一個抽屜中會放兩個蘋果。
由題目我們可知,至少有一個數會出現兩次。
然後我們採用分治的思想,將每個數的取值的區間[1,n]劃分成[1,n/2]和[n/2+1]兩個子區間,然後分別統計區間內數的個數。
注意:這裡的區間是指數的取值範圍,而不是陣列下標
劃分之後,左右兩區間中一定有一個區間,區間中數的個數大於區間長度。
最後利用二分方法,不斷縮小區間長度,當區間長度為1時,即為本題的答案。
複雜度分析:利用二分縮小區間\(O(logn)\)
public: int duplicateInArray(vector<int>& nums) { int l=1,r=nums.size()-1; while(l<r) { int s=0; int mid=(l+r)>>1; for(auto x:nums) if(x>=l&&x<=mid) s++; if(s>=mid-l+1) r=mid; else l=mid+1; } return r; } };