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

2021-08-20 07:13:48 字數 2694 閱讀 9027

題目描述:

陣列中有乙個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入乙個長度為9的陣列,由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2.

這道題出自《劍指offer》中的面試題。

一種簡單的演算法是,先對陣列進行排序,排序之後位於陣列中間的數字就一定是出現次數超過陣列長度一半的數字。排序演算法的時間複雜度為o(nlogn)。

下面是兩個o(n)的演算法。

解法一:根據陣列特點的o(n)演算法

陣列中有乙個數字出現的次數超過陣列長度的一半,也就是說它出現的次數比其他所有的數字出現次數的和都要多。因此在遍歷陣列的時候我們需要記錄兩個值:乙個是數字,乙個是次數。當我們遍歷到下乙個數字的時候,如果下乙個數字和我們之前儲存的值相同,則次數+1;如果下乙個陣列和我們之前寶尊的數字不同,則次數-1。如果次數為0,我們需要儲存下乙個數字,並把次數設為1.由於我們要找的數字出現的次數比其他所有的數字出現的次數的和還要多,那麼要找的數字肯定是最後一次把次數設為1時對應的數字。

基於該思想我們有如下的**:

class solution

else if(result == numbers[i])

times++;

else

times--;

} //此時result已經是陣列中出現次數最多的數字

//下面進行檢驗,result是否超過陣列元素的一半。

int c_times = 0;

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

if(c_times*2 > length)

return result;

return 0;

}};int main()

; int ret = 0;

solution sol;

ret = sol.morethanhalfnum(num, sizeof(num)/sizeof(num[0]));

cout << "陣列中出現次數超過一半的數字是: ";

cout << ret 《解法二:基於快排的o(n)的演算法

陣列中有乙個數字出現的次數超過了陣列長度的一半。如果把這個陣列排序,那麼排序之後位於陣列中間的數字一定就是那個出現次數超過陣列長度一半的數字,這個數字就是中位數。使用快排找出中位數,返回中位數就找到了這個數字。

在隨機快排演算法中,我們先在陣列找那個隨機選擇乙個數字,然後調整陣列中數字的順序,使得比選中數字小的數字都排在它的左邊,比選中數字大的數字都排在它的右邊。如果這個被選中的數字的下標剛好是n/2,那麼這個數字就是中位數。如果它的下標大於n/2,那麼中位數在它的左邊,我們就可以在它左邊部分的陣列中去找。如果它的下標小於n/2,那麼中位數應該位於它的右邊,我們可以在它的右邊部分的陣列中去找。這是乙個遞迴的過程。

//由快排演算法找出中位數,返回中位數。

class solution2

void swap(int* a,int* b)

//劍指offer中的partition函式,比較難理解

int partition(int data,int length,int start,int end)

}++small;

swap(&data[small],&data[end]);

//此時small左邊的值比它小,small右邊的值比它大

return small;

}        //常規的partition演算法,更簡單理解一些。

int partition2(int data,int length,int start,int end)

return start;

} int morethanhalfnum(int* numbers,int length)

else

}int result = numbers[middle];

//檢測該數字的次數是不是超過陣列元素的一半

int times = 0;

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

if(times * 2 > length)

return result;

return 0;

}};int main()

; int ret = 0;

solution2 sol;

ret = sol.morethanhalfnum(num, sizeof(num)/sizeof(num[0]));

cout << "陣列中出現次數超過一半的數字是: ";

cout << ret 《解法三:使用雜湊表

在乙個大小為256的陣列中,陣列下標為表示的是要查詢的陣列中的元素。初始化為0,如果要查詢的陣列的2出現了5次,那麼在hashtable[2]=5.

class solution3

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

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

//沒有找到這樣的數字

return 0;

} };int main()

; int ret = 0;

solution3 sol;

ret = sol.morethanhalfnum(num, sizeof(num)/sizeof(num[0]));

cout << "陣列中出現次數超過一半的數字是: ";

cout << ret

}

o(∩_∩)o

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

何海濤 劍指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...