從當前元素繼續尋找 尋找陣列中的重複數字

2021-10-14 18:31:41 字數 4533 閱讀 1263

有乙個陣列,現要找出陣列中任意乙個重複的元素。它的規則如下:

給定乙個長度為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 沒有主要元素。題目給了一種遞迴的演...