程式設計之美系列之二 尋找出現頻率超過一半的數

2021-06-18 18:52:32 字數 1265 閱讀 1072

問題描述:

現在有一陣列存放int型整數,數字有重複,且有一數字出現的頻率超過了50%,請找出這個數字。

補充:主要考慮資料量很大的情況。

問題求解:

分析:

最直接的方法就是對陣列中所有的數字排序,然後再掃瞄一遍,統計各個數字出現的次數,如果某個數字出現的次數超過一半,則輸出這個數字。顯然這個演算法的時間複雜度是o(n * log2n + n)。

事實上,假如現在陣列已經有序,那麼陣列中間的數字一定是這個要求的數字,所以根本不必掃瞄。此時演算法的時間複雜度是o(n * log2n + 1)。

那還能不能再簡化一些呢?

我們看到,演算法主要的消耗在排序這塊,那能否跳過排序這個步驟呢?我們這樣想,假如每次刪除兩個不同的數(不管包括不包括最高頻數),那麼,在剩下的數字裡,原最高頻數出現的頻率一樣超過了50%,不斷重複這個過程,最後剩下的將全是同樣的數字,即最高頻數。此演算法避免的排序,時間複雜度只為o(n)。

**如下:

1

static

intint

num)212

else

1319}20

return

candidate;21}

這個演算法體現了電腦科學中一種很普遍的思想,就是把乙個問題轉化為規模較小的若干個問題。分治、遞迴、貪心等都是基於這樣的思想。轉化的效率越高,轉化之後問題的規模縮小的越快,則正題的時間複雜度越低。

擴充套件問題:

現在陣列中沒有出現頻率一半的數字了,但有三個都超過了四分之一,找到他們。

分析:

與原問題一樣,只要降低規模即可,每次去掉四個不相同的數字,一直重複,最後剩下的三個數字就是答案。

**如下:

1

static

intcandia =0

, candib =0

, candic =0

;2static

void

findthreemost(

int num)320

}21else

if(countb ==0

)2232}

33else

if(countc ==0

)3444}

45}4647

else

4861}62

}63}

本文出自:

程式設計之美系列之二 尋找出現頻率超過一半的數

問題描述 現在有一陣列存放int型整數,數字有重複,且有一數字出現的頻率超過了50 請找出這個數字。補充 主要考慮資料量很大的情況。問題求解 分析 最直接的方法就是對陣列中所有的數字排序,然後再掃瞄一遍,統計各個數字出現的次數,如果某個數字出現的次數超過一半,則輸出這個數字。顯然這個演算法的時間複雜...

程式設計之美系列之尋找最大的K個數

題目描述 有很多無序的數,姑且家丁它們各不相等,怎麼選出其中最大的若干個數呢?這裡我不想去寫一些很沒有意義的思路。神馬先排序取前k個這種弱爆了並且一點也不適用的思想我就不想廢話了,因為如果資料量很大的時候,對所有資料排序肯定是費力不討好的事情,換換思路,不能全部排序,那就部分排序吧!這裡介紹兩個比較...

程式設計之美系列之二叉樹1 二叉樹中的距離問題

先來點基礎的,更多擴充套件,請猛擊 1 首先來個入門級的,求二叉樹的深度 include includestruct node const int n 20 node node n void add int root,int num,bool isleft else inline int max c...