No 3 陣列中重複的數字 P39

2021-09-26 03:24:28 字數 1798 閱讀 5195

題目1:找出陣列中重複的數字

【題目描述】

在乙個長度為n的陣列裡的所有數字都在0到n-1的範圍內。 陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中任意乙個重複的數字

例如,如果輸入長度為7的陣列,那麼對應的輸出是重複的數字2或者3。

【思路】

方法1:先排序,後比較

最簡單直接的方式,先對陣列進行排序,然後從頭到尾掃瞄陣列。時間複雜度為o(nlogn),空間複雜度為o(1).

方法2:雜湊表

如何進一步降低空間複雜度? 可以採用雜湊表。

從頭到尾掃瞄整個陣列,每掃瞄乙個數字的時候先判斷hash table中是否已經包含該數字,如果包含,則找到重複的數字;如果不包含,則將該數字加入到hash table中。

時間複雜度為o(n),空間複雜度為o(n)。

方法3:位置交換

如何在保證低空間複雜度的情況下,降低空間複雜度?我們可以通過題目設定的條件進一步思考。

審題可知陣列中總共有n個數字,並且這n個數字的取值範圍是[0, n-1],也就是說,如果整個陣列沒有重複數字的話,那麼每個數字 i 都可以放到第 i+1 的位置上。相反,如果有重複數字出現,那麼這樣的存放方法是不可行的。基於這一考慮,我們可以採用如下辦法: 從左到右掃瞄陣列a,對於位置 $i \in [0, n-1]$, 如果$a[i] = i$, 則繼續掃瞄下一位置 i+1;如果$a[i] \neq i$, 則比較數字a[i]與位置a[i]上的數字,如果相等,說明出現重複數字a[i],如果不等,則將兩個數字置換,然後再次對位置 i上的數字重複上述操作。

題目2:不修改陣列找出重複的數字

【題目描述】

在乙個長度為n+1的陣列裡的所有數字都在1到n的範圍內,所以陣列中至少有乙個數字是重複的。請找出陣列中任意乙個重複的數字,並且不能修改輸入的陣列。

例如,如果輸入長度為8的陣列,那麼對應的輸出是重複的數字2或者3。

【思路】

方法1:把數字插入到輔助陣列

與題目1類似,但是要求不能改變原始陣列,因此我們可以採用題目1中的方法3類似的思想(i.e. 讓數字歸位到對應的index上)。建立乙個輔助陣列,將原陣列中的數字依次放入到輔助陣列中對應的位置上,這樣很容易發現那個數字是重複的。時間複雜度為o(n),空間複雜度為o(n)。

方法2:二分查詢統計

如何避免使用o(n)的輔助空間呢?

將數字1~n從中間數字m分成兩部分,前一半為1~m,後一半為m+1~n。在陣列中檢索1~m這幾個數字出現的次數之和(即1<= x <=m),如果數目超過m,說明這一半區間內肯定包含重複數字,否則重複數字肯定包含在另一半內。接下來,可以繼續把包含重複數字的區間一分為二,直到找到某個重複的數字。

二分的次數為o(logn),每次需要o(n)的時間來統計數字出現次數,因此總時間複雜度為o(nlogn),空間複雜度為o(1)。

需要注意的是,該方法不能保證找出所有重複的數字。比如,不能找出重複數字2,因為1~2中只有2個數字,並且該範圍內的數字也只出現了2次。

劍指offer 陣列中的重複的數字 p39

c 中的stl中的vector stl中的vector每次擴容量時,新的容量都是之前一次的兩倍 在c c 中,陣列和指標是相互關聯又有區別的兩個概念。關聯 當我們宣告乙個陣列時,其陣列的名字也是乙個指標,該指標指向陣列的第乙個元素。我們可以用乙個指標來訪問陣列。這裡是因為作者的編輯環境是在win64...

3 陣列中重複的數字

include using namespace std bool duplicate int numbers,int length,int duplication 檢查每乙個元素 for int i 0 i length i for int i 0 i length i int temp numbe...

劍指offer(39)陣列中重複的數字

在乙個長度為n的陣列裡的所有數字都在0到n 1的範圍內。陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中任意乙個重複的數字。例如,如果輸入長度為7的陣列,那麼對應的輸出是第乙個重複的數字2。設定乙個比較陣列 返回值即可 重複了就break public bo...