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

題目:數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。

方法一:基于Partition函數的O(n)算法
數組中有一個數字出現的次數超過了數組長度的一半,那么這個數一定是這個數組的中位數。我們需要找到這個數組的第n/2大的數字。所以問題轉化成找數組中第k大的數這樣的問題。
跟快速排序的Partition函數一樣,我們隨機選擇數組中的一個數字,調整數組中數字的順序,使得比選中數字小的都在它的左邊,其它的都在它右邊。如果這個選中的數字的下標剛好是n/2,那么這個數字就是數組中的中位數。如果它的下標大于n/2,那么中位數應該位于它的左邊,如果它的下標小于n/2,那么中位數位于它的右邊。

方法二:
在遍歷數組的時候保存兩個值:一個是數組中的一個數字,一個是次數。當遍歷下一個數字的時候,如果上一個數字和之前保存的數字相同,則次數加1,如果不同,則次數減1。如果次數為零,則需要保存下一個數字,并把次數設為1。

下面的Python代碼分別實現了上面兩種方法:

#encoding=utf8
'''
題目:數組中有一個數字出現的次數超過數組長度的一半,找出這個數字
'''
 
def partition(num_list, start, end):
    '''將num_list從start開始,到end結束的部分分組,以start位置的數字為基準,返回基準最后所在的位置'''
    
    pivot = num_list[start]
    while start < end:
        while start < end and num_list[end] >= pivot:end -= 1
        if start < end:num_list[start] = num_list[end]
        while start < end and num_list[start] <= pivot:start += 1
        if start < end:num_list[end] = num_list[start]
    num_list[start] = pivot
    return start
        
def find_half_num_1(num_list):
    '''返回num_list中間的數字'''
    
    if type(num_list) != type([]) or len(num_list) == 0:
        return None
    start = 0
    end = len(num_list) - 1
    middle = end / 2
    
    index = partition(num_list, start, end)
    while index != middle:
        if index > middle:
            end = index - 1
            index = partition(num_list, start, end)
        else:
            start = index + 1
            index = partition(num_list, start, end)
            
    return num_list[middle]
 
def find_half_num_2(num_list):
    if type(num_list) != type([]):
        return None
    
    result = None
    time = 0
    for i in range(0, len(num_list)):
        if time == 0:
            result = num_list[i]
            time = 1
        else:
            if num_list[i] == result:
                time += 1
            else:
                time -= 1
    return result
 
if __name__ == '__main__':
    l_1 = [1,2,3,4,5,6,7,8,2,2,2,2,2,2,2,2,2,2,2,2]
    l_2 = []
    l_3 = [1,2,3,4,5,6,7,8,9,9,9,9,9,9,9,9,9,9,9,9]
    l_4 = None
    l_5 = [5]
    print find_half_num_1(l_1)
    print find_half_num_1(l_2)
    print find_half_num_1(l_3)
    print find_half_num_1(l_4)
    print find_half_num_1(l_5)
    print find_half_num_2(l_1)
    print find_half_num_2(l_2)
    print find_half_num_2(l_3)
    print find_half_num_2(l_4)
    print find_half_num_2(l_5)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容