問題描述:
現在有一陣列存放int型整數,數字有重複,且有一數字出現的頻率超過了50%,請找出這個數字。
補充:主要考慮資料量很大的情況。
問題求解:
分析:
最直接的方法就是對陣列中所有的數字排序,然後再掃瞄一遍,統計各個數字出現的次數,如果某個數字出現的次數超過一半,則輸出這個數字。顯然這個演算法的時間複雜度是o(n * log2n + n)。
事實上,假如現在陣列已經有序,那麼陣列中間的數字一定是這個要求的數字,所以根本不必掃瞄。此時演算法的時間複雜度是o(n * log2n + 1)。
那還能不能再簡化一些呢?
我們看到,演算法主要的消耗在排序這塊,那能否跳過排序這個步驟呢?我們這樣想,假如每次刪除兩個不同的數(不管包括不包括最高頻數),那麼,在剩下的數字裡,原最高頻數出現的頻率一樣超過了50%,不斷重複這個過程,最後剩下的將全是同樣的數字,即最高頻數。此演算法避免的排序,時間複雜度只為o(n)。
**如下:
else
}return candidate;
}這個演算法體現了電腦科學中一種很普遍的思想,就是把乙個問題轉化為規模較小的若干個問題。分治、遞迴、貪心等都是基於這樣的思想。轉化的效率越高,轉化之後問題的規模縮小的越快,則正題的時間複雜度越低。
擴充套件問題:
現在陣列中沒有出現頻率一半的數字了,但有三個都超過了四分之一,找到他們。
分析:
與原問題一樣,只要降低規模即可,每次去掉四個不相同的數字,一直重複,最後剩下的三個數字就是答案。
**如下:
static int candia = 0, candib = 0, candic = 0;
static void findthreemost(int num)
}else if (countb == 0)
}else if (countc == 0)}}
else}}
}
程式設計之美系列之二 尋找出現頻率超過一半的數
問題描述 現在有一陣列存放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...