數組中出現次數超過一半的數


title: 2019-8-25 數組中出現次數超過一半的數
tags: 算法,每日一題,矩陣打印


數組中出現次數超過一半的數

1. 問題描述

數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度爲9的數組{1,2,3,2,2,2,5,4,2}。由於數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。

2. 題目解析

這道題目是關鍵是如何記錄數組中每個數出現的次數或者用什麼方法能夠快速找到最有可能是出現次數最多的那個數。

2.1 具體思路

這裏提供了三種方法:

方法一:使用map記錄數組中每個數出現的次數,最後遍歷一遍map,找到有沒有出現次數超過一半的數。

方法二:先對數組進行排序,那麼最有可能是出現次數超過一半的數一定在數組的中間位置。最後再遍歷一遍確定是不是真的是這個數。

方法三:這種方法比較取巧,時間複雜度爲O(2n),空間複雜度爲O(1)。具體的做法就是記錄兩個值cur_numcur_count;cur_num記錄的是當前最可能是出現次數過半的數字,cur_count表示的是一個相對的出現次數。具體過程可以看圖。

數組中出現次數過半的數

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        if(numbers.empty()) return 0;
        return MoreThanHalfNum_Solution3(numbers);
    }
    int MoreThanHalfNum_Solution1(vector<int>& numbers){//方法一:藉助map
        unordered_map<int, int> num_count_map;
        for (int i=0; i<numbers.size(); ++i){
            auto it = num_count_map.find(numbers[i]);
            if(it == num_count_map.end()){
                num_count_map[numbers[i]] = 1;
            }else{
                num_count_map[numbers[i]]++;
            }
        }
        int num_half_size = numbers.size() / 2;
        auto it = num_count_map.begin();
        while(it != num_count_map.end()){
            if(it->second > num_half_size) return it->first;
            ++it;
        }
        
        return 0;
    }
    
     int MoreThanHalfNum_Solution2(vector<int>& numbers){//方法二:對數組進行排序,那麼如果存在大於數組長度一半的數那麼一定是中間位置的數
         sort(numbers.begin(), numbers.end());
         int num_size = numbers.size();
         int middle_num = numbers[num_size/2];
         
         int count = 0;
         for (int i=0; i<numbers.size(); ++i){
             if (numbers[i] == middle_num) ++count;
         }
         
         if (count > num_size/2) return middle_num;
         else return 0;
         
     }
    
    int MoreThanHalfNum_Solution3(vector<int>& numbers){//方法三:
        int cur_num = numbers[0];
        int cur_count = 0;
        
        auto it = numbers.begin();
        while(it != numbers.end()){
            if(*it == cur_num) ++cur_count;
            else --cur_count;
            
            if(cur_count == 0){
                cur_num = *it;
                cur_count = 1;
            }
            ++it;
        }
        
        //這裏還是要判斷遍歷判斷依次,對於否者對於1 1 1 2 2 2這種情況會輸出2
         int num_size = numbers.size();
         
         int count = 0;
         for (int i=0; i<numbers.size(); ++i){
             if (numbers[i] == cur_num) ++count;
         }
         
         if (count > num_size/2) return cur_num;
         else return 0;
        
    }
    
};

更多關於編程和機器學習資料請關注FlyAI公衆號。
公衆號二維碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章