有乙個陣列,現要找出陣列中任意乙個重複的元素。它的規則如下:
給定乙個長度為n的陣列,陣列中每個元素的取值範圍為:0~n-1
陣列中某些數字是重複的,但是不知道哪些數字重複了,也不知道重複了幾次
求陣列中任意乙個重複的數字
這個問題的實現思路有三種:
接下來,我們來一一講解下這三種實現思路。
用排序方法實現分為兩步:
先用快速排序對陣列進行排序
遍歷排序好的陣列,如果其相鄰的兩個元素相等就代表陣列中有重複的數字,將其返回即可。
接下來,我們通過乙個例子來驗證下上述思路。
宣告乙個陣列:[8, 1, 2, 3, 4, 3, 3, 4, 5]
用快速排序對上述陣列進行排序,排序好的陣列為:[1, 2, 3, 3, 3, 4, 4, 5, 8]
遍歷陣列,判斷i號位置的元素與i+1位置的元素是否相等。
i = 0時,i號位置的元素為1,i+1位置的元素是2,1 !== 2
,繼續下一輪遍歷
i = 1時,i號位置的元素為2,i+1位置的元素是3,2 !== 3
,繼續下一輪遍歷
i = 2時,i號位置的元素為3,i+1位置的元素是3,3 === 3
,陣列中有重複數字,儲存i號位置的元素,退出迴圈。
返回找到的重複數字
時間複雜度分析:呼叫快速排序其時間複雜度為o(nlog(n))
,陣列排序完成後只需遍歷陣列找到相鄰的就退出,因此總的時間複雜度為o(nlog(n))
空間複雜度分析:空間複雜度分析:由於沒有宣告新的空間,因此空間複雜度為o(1)
使用排序方法我們可以解決這個問題,但是需要對陣列進行排序,時間複雜度偏高。
我們可以額外宣告乙個雜湊表,然後遍歷陣列,判斷陣列中的元素是否已存在於雜湊表中,如果不存在就將其放入雜湊表中,否則就代表陣列中有重複元素,將其返回即可。
它的實現思路如下:
宣告乙個空的雜湊表
從頭到尾遍歷陣列,如果當前遍歷到的元素不存在與雜湊表中,就把它加入雜湊表,否則就返回這個元素
接下來,我們通過乙個例子來驗證下上述思路。
宣告乙個陣列:[8, 1, 2, 3, 4, 3, 3, 4, 5]
宣告乙個雜湊表:const hashmap = new hashmap()
遍歷陣列,判斷陣列中的元素是否在雜湊表中。
i = 0時,i號位置的元素為8,不在雜湊表中,將其放入雜湊表。
i = 1時,i號位置的元素為1,不在雜湊表中,將其放入雜湊表。
i = 2時,i號位置的元素為2,不在雜湊表中,將其放入雜湊表。
i = 3時,i號位置的元素為3,不在雜湊表中,將其放入雜湊表。
i = 4時,i號位置的元素為4,不在雜湊表中,將其放入雜湊表。
i = 5時,i號位置的元素為3,在雜湊表中,儲存i號位置的元素,終止迴圈。
返回找到的重複數字
時間複雜度分析:遍歷陣列,判斷雜湊表中是否包含當前遍歷到的元素時,都可以用o(1)
的時間複雜度完成,所有元素遍歷完就需要n個o(1),因此總的時間複雜度為o(n)
空間複雜度分析:由於需要乙個額外的雜湊表來儲存資料,情況最壞時陣列的所有元素都會放進雜湊表中,因此總的空間複雜度為:o(n)
使用雜湊表輔助實現時,我們將時間複雜度降低了,但是代價是用了o(n)
的空間儲存雜湊表,我們用空間換取了時間。
根據題意可知,陣列中元素的取值範圍在0~n-1,那麼就可以得到如下結論:
根據上述結論,我們可以得出下述實現思路:
從頭到尾遍歷陣列,儲存第i號位置的元素,用m表示
如果m的值等於當前下標(i),則繼續遍歷。
接下來,我們通過乙個例子來驗證下上述思路。
宣告乙個陣列:[8, 1, 2, 3, 4, 3, 3, 4, 5]
此時,m的值為8,8 != 0
,陣列8號位置的元素為5,8 != 5
,則交換array[0]
和array[8]
的位置,更新m的值。交換位置後的陣列為:[5, 1, 2, 3, 4, 3, 3, 4, 8]
此時,m的值為5,5 != 0
,陣列5號位置的元素為3,3 != 5
,則交換array[0]
和array[5]
的位置,更新m的值。交換位置後的陣列為:[3, 1, 2, 3, 4, 5, 3, 4, 8]
此時,m的值為3,3!=0
,陣列3號位置的元素為3,3 === 3
,元素重複,返回m。
問題解決,重複數字為3。
時間複雜度分析:每個數字最多只要交換2次就能找到它的位置,因此總的時間複雜度為o(n)
空間複雜度分析:所有操作都在原陣列進行,沒有用到額外的空間,所以空間複雜度為o(1)使用動態排序法實現時,我們只是改變了陣列的元素順序,沒有使用額外的空間,因此空間複雜度降低了,同時時間複雜度又保持在了
o(n)
。所以,這種解法相對與前面兩種而言是最優的。
接下來,我們來看看如何將其實現,此處我們使用typescript將其實現,我們先來看看如何設計這個類。
根據題意可知,並非所有陣列都能使用上面的方法來求解。因此我們在設計類的時候,要判斷呼叫者傳入的引數是否滿足題意。
export class arrayrepeatednumber
for (let i = 0; i if (array[i] 0 || array[i] > array.length - 1)
}this.sort = new sort(array);}}
接下來,我們來看看上述三種實現思路的**。
getrepeatedtosort(): number | void
}return val;}}
getrepeatedtohashmap(): number | void
// 不存在,將其加入雜湊表
hashmap.put(this.array[i], 0);
}return val;}}
getrepeated(): number | void
// 交換陣列的i號位置的元素和m號位置的元素
[this.array[i], this.array[m]] = [this.array[m], this.array[i]];
// 交換完畢,更新m的值
m = this.array[i];}}
// 未找到
return -1;}}
完整**,請移步:arrayrepeatednumber.ts
我們用上面舉的例子來驗證下上述**是否正確執行。
尋找陣列中的主要元素
對於乙個大小為n的整數陣列,將其中出現次數大於n 2的元素稱為主要元素,例如中主要元素是5,而中則沒有。似乎是乙個統計陣列元素出現次數的問題,因此尋找出現次數最多的元素的解法在這裡也適用。不過該問題有乙個特點 即要求元素出現次數過半。因此,如果存在這樣的主要元素x,將它與陣列所有元素進行比較,相等則...
從字串陣列中尋找數字的元素
前幾天insus.net有寫過一篇 從字串陣列中把數字的元素找出來 那是寫乙個類別來處理數字元素並收集起來。開發程式,解決方法不是唯一的。相同的功能實現,方法不止乙個。下面insus.net再使用另外的方法來實現,算作對基礎知識的鞏固與掌握。參考下面 上面 21至 30行 可以改用yield方法,返...
在陣列中尋找主要元素
來自 資料結構與演算法分析 c語言描述 練習2.19 問題描述 大小為 n 的陣列 a 其主要元素是乙個出現次數超過 n 2 的元素 從而這樣的元素最多有乙個 例如,陣列 3,3,4,2,4,4,2,4,4 有乙個主要元素4,而陣列 3,3,4,2,4,4,2,4 沒有主要元素。題目給了一種遞迴的演...