(python)劍指Offer 陣列中重複的數字

2022-03-22 06:45:09 字數 2704 閱讀 1073

在長度為n的陣列中,所有的元素都是0到n-1的範圍內。 陣列中的某些數字是重複的,但不知道有幾個重複的數字,也不知道重複了幾次,請找出任意重複的數字。 例如,輸入長度為7的陣列,那麼對應的輸出為2或3。

1、判斷輸入陣列有無元素非法 

2、從頭掃到尾,只要當前元素值與下標不同,就做一次判斷,numbers[i]與numbers[numbers[i]],相等就認為找到了重複元素,返回true,否則就交換兩者,繼續迴圈。直到最後還沒找到認為沒找到重複元素,返回false

時間複雜度:o(n),空間複雜度:o(1)

#在長度為n的陣列中,所有的元素都是0到n-1的範圍內。 陣列中的某些數字是重複的,但不知道有幾個重複的數字,

#也不知道重複了幾次,請找出任意重複的數字。 例如,輸入長度為7的陣列,那麼對應的輸出為2或3

def repeat_num(li):

for index, value in enumerate(li):

if index != value:

li[index], li[value] = li[value], li[index]

if index != value and value == li[value]:

return li[index]

li = [0, 1, 2, 3, 3, 4, 6, 4]

print(repeat_num(li))

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

思路:

採用二分法查詢,時間複雜度為o(nlogn)

在數字1~n中取中間值m= (1+n) / 2, 此時數字包括1~m,m+1~n兩段;

遍歷陣列,獲得數字1~m的個數;

如果數字1~m的個數大於m,說明1~m這一段內肯定有重複數字,那麼在這一段內繼續取中間值比較;

如果數字1~m的個數等於m,這一段不一定有重複數字,比較後一段;

如果數字1~m的個數小於m,說明m+1~n這一段一定有重複數字,在後一段取中間值比較;

按照上述方法一直取中間值比較,直到只剩乙個數字且這個數字出現次數超過 1 ,該數字即為重複數字

class solution():

def duplicate(self,numbers):

if numbers == :

return false

length = len(numbers)

start = 1

end = length - 1

while end >= start:

middle = (end - start)//2 + start

count = self.countnum(numbers, length, start, middle)

if end == start:

if count > 1:

return true

else:

break

if count > middle - start + 1:

end = middle

else:

start = middle + 1

return false

def countnum(self, numbers, length, start, end):

count = 0

for i in range(length):

if numbers[i] < 1 or numbers[i] > length:

return false

if start <= numbers[i] <= end:

count += 1

return count

ss = solution()

print(ss.duplicate([4,2,3,1,2,5]))

print(ss.duplicate([4,2,3,1]))

這種方法雖然不需要輔助空間o(n),但是後面每半個區間都需要遍歷整個陣列,函式countnum將被呼叫o(logn)次,每次需要o(n)的時間,因此總的時間複雜度是o(nlogn),空間複雜度為o(l)。相當於用時間換空間了。

現在來總結下關於陣列中重複數字的問題,利用輔助空間的話,時間和空間複雜度都是o(n);利用下標於數字對應關係的話時間複雜度是o(n),空間複雜度是o(l),但是需要改變陣列;利用二分查詢類似思路的方法,時間複雜度是o(nlogn),空間複雜度o(l),所以要問清楚面試官他想要空間效率高的呢?還是時間效率高的呢?能不能改變陣列呢?一方面體現交流能力,一方面能最快的寫出答案。

劍指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 問題描述 在乙個長度...