<劍指Offer>面試題39: 數(shù)組中出現(xiàn)次數(shù)超過一半的數(shù)字

題目描述 咆迹客網(wǎng)

  • 數(shù)組中有一個數(shù)字出現(xiàn)的次數(shù)超過數(shù)組長度的一半,請找出這個數(shù)字
  • 例如,輸入一個長度為 9 的數(shù)組 {1,2,3,2,2,2,5,4,2}。由于數(shù)字2在數(shù)組中出現(xiàn)了5次翩活,超過數(shù)組長度的一半阱洪,因此輸出2。如果不存在則輸出0

題目解讀

  • 劍指Offer 205
  • 思路一菠镇、基于 Partition 函數(shù)的時間復雜度為 O(n) 的算法
  • 思路二冗荸、基于數(shù)組特點找出時間復雜度為 O(n) 的算法
  • 思路三、map 實現(xiàn)利耍。key存儲數(shù)字蚌本,value存儲次數(shù),出現(xiàn)次數(shù)超過數(shù)組長度的一半則找到數(shù)字

代碼

  • 思路一隘梨、基于 Partition 函數(shù)的時間復雜度為 O(n) 的算法
    考慮數(shù)組的特性:數(shù)組中有一個數(shù)字出現(xiàn)的次數(shù)超過數(shù)組長度的一半程癌。如果把這個數(shù)組排序,那么排序之后位于數(shù)組中間的數(shù)字一定就是那個出現(xiàn)次數(shù)超過數(shù)組長度一半的數(shù)組轴猎。
    這種算法受到快速排序的啟發(fā)
#include<iostream>
#include<vector>
using namespace std;

class Solution {
public:
    int Paritition1(vector<int>& numbers, int left, int right){
        int pivot = numbers[left];
        while(left < right){

            while(left < right && numbers[right] >= pivot){
                right --;
            }
            numbers[left] = numbers[right];

            while(left < right && numbers[left] <= pivot){
                left ++;
            }
            numbers[right] = numbers[left];
        }
        numbers[left] = pivot;
        return left;
    }

    bool checkVality(vector<int> numbers, int result){
        bool vality = true;
        int times = 0;
        int len = numbers.size();
        for(int i=0; i < len; i++){
            if(result == numbers[i]){
                times ++;
            }
        }

        if(times * 2 <= len){
            vality = false;
        }
        return vality;
    }

    int MoreThanHalfNum_Solution(vector<int>& numbers) {
        if(numbers.size() == 0){
            return 0;
        }

        int middle = numbers.size() >> 1;
        int left = 0;
        int right = numbers.size() - 1;
        int pivot = Paritition1(numbers, left, right);

        while(pivot != middle){
            if(pivot > middle){
                right = pivot - 1;
            }
            else{
                left = pivot + 1;
            }
            pivot = Paritition1(numbers, left, right);
        }

        int result = numbers[middle];
        if(!checkVality(numbers, result)){
            result = 0;
        }
        return result;
    }
};

int main(){
    int a[10] = {2, 2, 2, 2, 2, 1, 3, 4, 5};
    int len = 9;
    vector<int> numbers;
    Solution ss;

    for(int i=0; i < len; i++){
        numbers.push_back(a[i]);
    }
    cout<<ss.MoreThanHalfNum_Solution(numbers)<<endl;
}
  • 思路二嵌莉、基于數(shù)組特點找出時間復雜度為 O(n) 的算法
    1、數(shù)組中有一個數(shù)字出現(xiàn)的次數(shù)超過數(shù)組長度的一半税稼,也就是說它出現(xiàn)的次數(shù)比其他所有數(shù)字出現(xiàn)的次數(shù)的和還要多。因此垮斯,我們可以考慮在遍歷數(shù)組的時候保存兩個值:一個是數(shù)組中的一個數(shù)字郎仆;另一個是次數(shù)。
    2兜蠕、當我們遍歷到下一個數(shù)字的時候扰肌,如果下一個數(shù)字和我們之前保存的數(shù)字相同,則次數(shù)加1熊杨;如果下一個數(shù)字和我們之前保存的數(shù)字不同曙旭,則次數(shù)減1;如果次數(shù)為0晶府,那么我們需要保存下一個數(shù)字桂躏,并把次數(shù)設(shè)為1.
    3、由于我們要找的數(shù)字出現(xiàn)的次數(shù)比其他所有數(shù)字出現(xiàn)的次數(shù)之和還要多川陆,那么要找的數(shù)字肯定是最后一次把次數(shù)設(shè)為1時對應的而數(shù)字
#include<iostream>
#include<vector>
using namespace std;

class Solution {
public:
    bool checkVality(vector<int> numbers, int result){
        bool vality = true;
        int times = 0;
        for(int i=0; i < numbers.size(); i++){
            if(result == numbers[i]){
                times ++;
            }
        }

        if(times * 2 <= numbers.size()){
            vality = false;
        }
        return vality;
    }

    int MoreThanHalfNum_Solution(vector<int> numbers) {
        if(numbers.size() == 0){
            return 0;
        }

        int times = 1;
        int result = numbers[0];
        for(int i=1; i < numbers.size(); i++){
            if(times == 0){
                result = numbers[i];
                times = 1;
            }
            else if(result == numbers[i]){
                times ++;
            }
            else{
                times --;
            }
        }

        if(!checkVality(numbers, result)){
            result = 0;
        }
        return result;
    }
};

int main(){
    int a[10] = {2, 2, 2, 2, 2, 1, 3, 4, 5};
    int len = 9;
    vector<int> numbers;
    Solution ss;

    for(int i=0; i < len; i++){
        numbers.push_back(a[i]);
    }

    cout<<ss.MoreThanHalfNum_Solution(numbers)<<endl;
}

總結(jié)展望

  • 有快排的思想在其中剂习,題目很好,值得反復思考
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末较沪,一起剝皮案震驚了整個濱河市鳞绕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌尸曼,老刑警劉巖们何,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異控轿,居然都是意外死亡冤竹,警方通過查閱死者的電腦和手機拂封,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贴见,“玉大人烘苹,你說我怎么就攤上這事∑浚” “怎么了镣衡?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長档悠。 經(jīng)常有香客問我廊鸥,道長,這世上最難降的妖魔是什么辖所? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任惰说,我火速辦了婚禮,結(jié)果婚禮上缘回,老公的妹妹穿的比我還像新娘吆视。我一直安慰自己,他們只是感情好酥宴,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布啦吧。 她就那樣靜靜地躺著,像睡著了一般拙寡。 火紅的嫁衣襯著肌膚如雪授滓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天肆糕,我揣著相機與錄音般堆,去河邊找鬼。 笑死诚啃,一個胖子當著我的面吹牛淮摔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播始赎,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼噩咪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了极阅?” 一聲冷哼從身側(cè)響起胃碾,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎筋搏,沒想到半個月后仆百,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡奔脐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年俄周,在試婚紗的時候發(fā)現(xiàn)自己被綠了吁讨。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡峦朗,死狀恐怖建丧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情波势,我是刑警寧澤翎朱,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站尺铣,受9級特大地震影響拴曲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凛忿,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一澈灼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧店溢,春花似錦叁熔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至叠赦,卻和暖如春驹马,著一層夾襖步出監(jiān)牢的瞬間革砸,已是汗流浹背除秀。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留算利,地道東北人册踩。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像效拭,于是被迫代替她去往敵國和親暂吉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容