題目二:不修改陣列找出重複的數字
相似題目
在乙個長度為n
的陣列裡的所有數字都在0 ~ n-1
的範圍內。 陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中任意乙個重複的數字。 例如,如果輸入長度為7的陣列,那麼對應的輸出是第乙個重複的數字
2
。
解決這個問題的乙個簡單的方法就是先把輸入陣列排序。從排序的陣列中找出重複的數字只需要從頭到尾掃瞄一遍排序後的陣列即可。
時間複雜度:o(n
logn
)o(nlogn)
o(nlog
n)從頭到尾掃瞄陣列中的每個數字,然後判斷雜湊表裡是否已經包含了這個數字。如果雜湊表裡還沒有這個數字,就把它加入雜湊表。如果雜湊表中已經存在該數字,就找到乙個重複的數字。
可以用set
來判斷是否存在,也可以用hashmap
來計數判斷是否出現過。
時間複雜度:o(n
)o(n)
o(n)
空間複雜度:o(n
)o(n)
o(n)
注意已知條件,長度為n
的陣列nums
,元素取值範圍在0 ~ n-1
,比較巧妙的想法就是交換元素,將nums[i]
放在下標為nums[i]
的位置,如果交換之前已經滿足nums[nums[i]] = nums[i]
,說明該元素已經被交換過,那麼就是乙個重複元素。
class
solution
int n = nums.length;
// 元素合法性檢查
for(
int i =
0; i++i)
for(
int i =
0; i < n;
++i)
swap
(nums, i, nums[i]);
}}return-1
;}private
void
swap
(int
nums,
int i,
int j)
}
時間複雜度:o(n
)o(n)
o(n)
287. find the duplicate number
給定乙個長度為n+1
的陣列nums
,陣列中所有的數均在1∼n
的範圍內,其中n≥1
。
請找出陣列中任意乙個重複的數,但不能修改輸入的陣列。
樣例
給定 nums = [2, 3, 5, 4, 3, 2, 6, 7]。
返回 2 或 3。
思考題:如果只能使用 o(1
)o(1)
o(1)
的額外空間,該怎麼做呢?
抽屜原理:n+1
個蘋果放在n
個抽屜裡,那麼至少有乙個抽屜中會放兩個蘋果
在本題中,一共有n+1
個數,每個數的取值範圍是[1, n]
,所以至少會有乙個數出現兩次。
另外,還有兩點需要注意:
所以跟前面一題的思路有些不同。我們採用分治的思想,將每個數的取值的區間[1, n]
劃分成[1, n/2]
和[n/2+1, n]
兩個子區間,然後分別統計兩個區間中數的個數。
注意這裡的區間是指元素的取值範圍,即nums[i]
,而不是陣列下標。
劃分之後,左右兩個區間裡一定至少存在乙個區間,區間中元素的個數大於區間長度。
這個可以用反證法來說明:如果兩個區間中元素的個數都小於等於區間長度,那麼整個區間中元素的個數就小於等於n
,和有n+1
個數矛盾。
因此我們可以把問題劃歸到左右兩個子區間中的乙個,而且由於區間中數的個數大於區間長度,根據抽屜原理,在這個子區間中一定存在某個數出現了兩次。
依次類推,每次我們可以把區間長度縮小一半,直到區間長度為1
時,我們就找到了答案。
class
solution
if(count > mid - l +1)
else
}return l;
}}
類似鍊錶找環的入口,陣列中的元素val
看作是結點值,nums[val]
看作是next域
,因為必然存在重複元素,所以必然存在「環」。
初始時慢指標slow
和快指標fast
均等於0
,而陣列中的元素是在[1,n]
範圍內,這相當於鍊錶中的dummy
虛假頭結點,即dummy.next = head
class
solution
return slow;}}
return-1
;}}
我們可以看到外層while
迴圈條件是一定成立的,因為「環」一定存在,所以也必然能有迴圈結束條件。但是要注意,如果初始用slow = nums[0]
,fast = nums[nums[0]]
,可能會出現死迴圈,例如nums =
442. find all duplicates in an array
面試題03 陣列中重複的數字
在乙個長度為 n 的陣列 nums 裡的所有數字都在 0 n 1 的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意乙個重複的數字。只輸出第乙個重複的數字 示例 1 輸入 2,3,1,0,2,5,3 輸出 2解決辦法 使用hashset 如果出現...
面試題03 陣列中重複的數字
找出陣列中重複的數字。在乙個長度為 n 的陣列 nums 裡的所有數字都在 0 n 1 的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意乙個重複的數字。示例 1 輸入 2,3,1,0,2,5,3 輸出 2 或 3 限制 2 n 100000 c...
面試題03 陣列中重複的數字
題目 在乙個長度為 n 的陣列 nums 裡的所有數字都在 0 n 1 的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意乙個重複的數字。示例 輸入 2,3,1,0,2,5,3 輸出 2 或 3 2 n 100000 int findrepeat...