找出陣列中出現次數超過一半的數字 百度

2021-06-06 12:07:31 字數 1944 閱讀 5326

題目:陣列中有乙個數字出現的次數超過了陣列長度的一半,找出這個數字。

看到這道題,我們馬上就會想到,要是這個陣列是排序的陣列就好了。如果是排序的陣列,那麼我們只要遍歷一次就可以統計出每個數字出現的次數,這樣也就能找出符合要求的數字了。題目給出的陣列沒有說是排好序的,因此我們需要給它排序。排序的時間複雜度是o(nlogn),再加上遍歷的時間複雜度o(n),因此總的複雜度是o(nlogn)。

接下來我們試著看看能不能想出更快的演算法。前面思路的時間主要是花在排序上。我們可以建立乙個雜湊表來消除排序的時間。雜湊表的鍵值(key)為陣列中的數字,值(value)為該數字對應的次數。有了這個輔助的雜湊表之後,我們只需要遍歷陣列中的每個數字,找到它在雜湊表中對應的位置並增加它出現的次數。這種雜湊表的方法在陣列的所有數字都在乙個比較窄的範圍內的時候很有效。

本部落格系列的第13題

就是乙個應用雜湊表的例子。不過本題並沒有限制陣列裡數字的範圍,我們要麼需要建立乙個很大的雜湊表,要麼需要設計乙個很複雜的方法來計算雜湊值。因此總體說來這個方法還不是很好。

前面兩種思路都沒有考慮到題目中陣列的特性:陣列中有個數字出現的次數超過了陣列長度的一半。也就是說,有個數字出現的次數比其他所有數字出現次數的和還要多。因此我們可以考慮在遍歷陣列的時候儲存兩個值:乙個是陣列中的乙個數字,乙個是次數。當我們遍歷到下乙個數字的時候,如果下乙個數字和我們之前儲存的數字相同,則次數加1。如果下乙個數字和我們之前儲存的數字不同,則次數減1。如果次數為零,我們需要儲存下乙個數字,並把次數設為1。由於我們要找的數字出現的次數比其他所有數字出現的次數之和還要多,那麼要找的數字肯定是最後一次把次數設為1時對應的數字。

基於這個思路,我們不難寫出如下**:

bool g_binputinvalid = false;//

// input: an array with "length" numbers. a number in the array

// "length / 2 + 1" times. otherwise, return 0 and set flag g_binputinvalid

// to be true. //

int morethanhalfnum(int* numbers, unsigned

int length)

if(numbers == null && length == 0)

g_binputinvalid = true;

return 0;

g_binputinvalid = false;

int result = numbers[0];

int times = 1;

for(int i = 1; i < length; ++i)

if(times == 0)

result = numbers[i];

times = 1;

else

if(numbers[i] == result)

times++;

else

times--;

// verify whether the input is valid

times = 0;

for(int i = 0; i < length; ++i)

if(numbers[i] == result)

times++;

if(times * 2 <= length)

g_binputinvalid = true;

result = 0;

return result;

在上述**中,有兩點值得討論:

(1)我們需要考慮當輸入的陣列或者長度無效時,如何告訴函式的呼叫者輸入無效。關於處理無效輸入的幾種常用方法,在

本部落格系列的第17題

中有詳細的討論;

(2)本演算法的前提是輸入的陣列中的確包含乙個出現次數超過陣列長度一半的數字。如果陣列中並不包含這麼乙個數字,那麼輸入也是無效的。因此在函式結束前我還加了一段**來驗證輸入是不是有效的。

找出陣列中出現次數超過一半的數

分析 最直接的方法,對陣列中所有的數排序,然後再掃瞄一遍,統計各個數出現的次數。如果某個數出現的次數超過一半,則輸出這個數。演算法的時間複雜度是o n log 2n n 如果每次刪除兩個不同的數,那麼,在剩下的數字裡,超過一半的數的個數一樣超過了50 不斷重複這個過程,最後剩下的即 為所求。無需避免...

演算法 找出陣列中出現次數超過一半的數

演算法 找出陣列中出現次數超過一半的數 每當我看到經典的演算法題,就懷念高中,感覺很多演算法題就是高中的題目,誰叫哥唯讀了個專科,高數基本相當沒學。有空要看看高數啊,想當年數學那是相當的.方法一 第乙個想到的方法是見乙個二維陣列,一維存陣列中的資料,二維存這個數出現的次數。出現次數最多的那個數就是要...

演算法 找出陣列中出現次數超過一半的數

演算法 找出陣列中出現次數超過一半的數 每當我看到經典的演算法題,就懷念高中,感覺很多演算法題就是高中的題目,誰叫哥唯讀了個專科,高數基本相當沒學。有空要看看高數啊,想當年數學那是相當的.include using namespace std class findtheone int b 2 new...