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

2021-08-26 11:17:13 字數 1728 閱讀 8081

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

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

logn),再加上遍歷的時間複雜度o(n),因此總的複雜度是o(n

logn)。

接下來我們試著看看能不能想出更快的演算法。前面思路的時間主要是花在排序上。我們可以建立乙個雜湊表來消除排序的時間。雜湊表的鍵值(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

intlength)

g_binputinvalid =

false;

intresult = numbers[0];

inttimes = 1;

for(int

i = 1; i < length; ++i)

else

if(numbers[i] == result)

times++;

else

times--;

}// verify whether the input is valid

times = 0;

for(

inti = 0; i < length; ++i) if

(times * 2 <= length)

return

result; }

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

我們需要考慮當輸入的陣列或者長度無效時,如何告訴函式的呼叫者輸入無效。關於處理無效輸入的幾種常用方法,在本部落格系列的第17題中有詳細的討論;

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

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

何海濤 劍指offer 名企面試官精講典型程式設計題 九度oj 題目描述 陣列中有乙個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入乙個長度為9的陣列。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。輸入 每個測試案例包括2行 第一行輸入乙個整數n 1 n 100000 表...

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

陣列中出現次數超過一半的數字 陣列中有乙個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入乙個長度為9的陣列。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。如果不存在則輸出0。class solution count 0 for auto i numbers if i k ...

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

題目描述 陣列中有乙個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入乙個長度為9的陣列。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。如果不存在則輸出0。解題思路 將陣列按大小排序,若存在數字出現次數超過陣列長度的一般,則陣列中位數必定為該數字 1 將陣列排序完成後,取a...