17_7_22 一個數組中有一個數字的次數超過了數組的一半,求出這個字符。

題目描述:
一個數組中有一個數字的次數超過了數組的一半,求出這個字符。如:int a[]={2,3,2,2,2,2,2,5,4,1,2,3},求出超過一半的數字是2。

難點分析:
如果,通過O(N)的時間複雜度,通過兩層循環,求出每個字符出現次數。發現有大於數組個數一半的,那麼就可以得到該字符。
但是,面試官是不希望看到這個答案的。那麼就需要一些比較巧妙的辦法了。

思路:
思路:
如果,某個字符出現次數大於數組總個數的一半。
那麼,該字符與其他字符,一個換一個的消除,該字符必然還有剩餘。
所以:我們可以定義一個ch存儲一個字符,flag表示消除過程中ch字符已知出現次數消除之後剩下的次數。
1,從頭開始遍歷,將遍歷過程中的字符與ch比較。
2,如果相同,則flag++,否則flag–;
3,當flag爲0時,表示該ch不滿足遍歷過程中題目要求條件。用數組下一個字符替換。
4,最終,遍歷完之後,ch保存的就是滿足題目要求的字符。

整個過程,只遍歷了一遍數組,時間複雜度O(N),空間複雜度O(1)

實現代碼:

#include <cassert> //使用到的頭文件

char char Check_More_Than_Halt(const char *arr, size_t size)
{
    assert(arr); //指針不能爲空
    assert(size);  //數組個數不能爲0

    int ch = arr[0];  //賦初值,在數組遍歷中可能會被替換
    int flag = 1;   //ch已出現一次
    int i = 1;   

    for (; i < size; ++i)
    {
        if (0 == flag)  //flag爲0時,需要更新ch
        {
            ch = arr[i];
            flag = 1;
        }
        else 
        {
            if (ch == arr[i]) //如果相等,則flag++;否則flag--。
                ++flag;
            else
                --flag;
        }
    }
    //此時,ch必定存儲出現次數大於數組個數一半的字符
    return ch;;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章