在乙個長度為n的陣列裡的所有數字都在0~n-1的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意乙個重複的數字。例如,如果輸入長度為7的陣列,那麼對應的輸出是重複的數字2或者3思路一
解決這個問題乙個簡單方法是把輸入的陣列排序,將陣列排序之後從排序的陣列中找出重複的數字是乙個很容易的事情,只需從頭到尾掃瞄排序後的陣列就可以了,排序乙個長度為n的陣列需要o(nlogn)時間。
思路二還可以用雜湊表來解決這個問題,從頭到尾掃瞄陣列中的每個數字,每掃瞄到乙個數字的時候,就可以用o(1)的時間來判斷雜湊表裡是否包含這個數字。如果雜湊表裡還沒有這個數字,就可以把它加入雜湊表裡。如果雜湊表包含這個數字,那麼就找到乙個重複數字。這個演算法的時間複雜度是o(n),但它提高效率是以乙個大小為o(n)的雜湊表為代價的。有沒有可能有更好的演算法,把空間複雜度降低到o(1),答案是有的。
思路三要想找到特定問題最優演算法,一定要觀察該特定問題的特點。而這個問題的特點是,陣列**現的數字都在0~n-1範圍之內。那麼根據這個特點,如果陣列中沒有重複數字,那麼應該下標和數字是一一對應的關係。當陣列**現重複數字之後,我們可以想象一下,會出現多個數字對應乙個下標,而有的下標不對應任何數字。
我們抓住這個特點,使用第二個雜湊表的思路,不過我們可以不用重新建立新的雜湊表。只需要在原有的陣列上改就可以了。簡單來說,我們就是捋順改列表中元素和位置對應關係,讓盡可能元素和位置是一一對應的。具體來說,從頭到尾掃瞄陣列中每個數字。當掃瞄到下標為i的數字時候,首先比較這個數字(比如說這個數字的值是m)是不是為等於i。如果是,接著掃瞄下乙個數字。如果該位置的數值m不等於i。那麼,就把這個數字m和第m個位置的數字進行比較,如果相等,就找到乙個重複數字。如果他和第m個位置的數字不想等,就把第i個位置和第m個位置的兩個位置的數字進行交換。把數字m放到他應有的位置上。
def
repeatable_num
(a):
if a ==
:return
"請輸入含有具體數值的陣列"
repeat_num =
for i in
range
(len
(a))
:if i != a[i]
:if a[i]
== a[a[i]]:
)else
: temp = a[i]
a[i]
= a[temp]
a[temp]
= temp
return repeat_num
劍指offer 陣列
資料是最簡單的資料結構,它佔據一塊連續的記憶體並按照順序儲存資料。建立陣列時,首先指點陣列的容量大小,然後根據大小分配記憶體。缺點 空間效率不高。經常有空閒的區域滅有得到充分利用。優點 時間效率很高。可以根據時間效率高的特點,來實現簡單的雜湊表 把陣列的下標設為雜湊表的鍵值,陣列中的每乙個數字設為雜...
劍指offer 陣列
public class 03 陣列中的重複數字 swap number,number i i return 1 交換 public void swap int number,int i,int j public class 03 陣列中的重複數字 return 1 public intfindre...
劍指offer 陣列
問題描述 在乙個二維陣列中 每個一維陣列的長度相同 每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成乙個函式,輸入這樣的乙個二維陣列和乙個整數,判斷陣列中是否含有該整數。function find target,array return false 問題描述 在乙個長度...