1. 程式人生 > >劍指offer——陣列中出現次數超過一半的數字

劍指offer——陣列中出現次數超過一半的數字

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

分析:

        第一種思路,把序列從小到大排個序,然後相同的數字一定是連續的,記錄連續數的個數,判斷其長度。時間複雜度為O(nlog(n)),時間主要用在排序上。

參考程式碼:

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        int sz = numbers.size();
        if( sz < 1)
            return 0;
        sort(numbers.begin(),numbers.end());
        int num = numbers[0];
        int cnt = 1;
        for( int i = 1; i < sz; i++)
        {
            if( numbers[i] == num)
                cnt++;
            else
            {
                if( cnt > sz/2)
                    break;
                else
                {
                    num = numbers[i];
                    cnt = 1;
                }
            }
        }
        if( cnt > sz/2)
            return num;
        else
            return 0;
    }
};

        第二種思路:假設存在出現次數超過原序列長度一般的數字,那麼我們可以通過cnt的加減來找到這個num,最後在遍歷一遍序列,計算該num出現的次數並加以判斷即可。這種方法的時間複雜度為O(n),比上一種方法簡潔。

參考程式碼:

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        int sz = numbers.size();
        if( sz < 1)
            return 0;
        int num = numbers[0];
        int cnt = 1;
        for( int i = 1; i < sz; i++)
        {
            if( cnt == 0)
            {
                num = numbers[i];
                cnt = 1;
            }
            else if( cnt > 0 && num == numbers[i])//這裡cnt>0是必然的,可不用做判斷
                cnt++;
            else
                cnt--;
        }
        
        cnt = 0;
        for( int i = 0; i < sz; i++)
        {
            if( numbers[i] == num)
                cnt++;
        }
        if( cnt > sz/2)
            return num;
        else
            return 0;
    }
};