1. 程式人生 > >【劍指Offer】26陣列中出現次數超過一半的數字

【劍指Offer】26陣列中出現次數超過一半的數字

題目描述

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

時間限制:1秒;空間限制:32768K;本題知識點:陣列

解題思路

思路一

先通過集合set得到去重後出現的數字,然後在原陣列中迴圈統計每個數字出現的次數,最後判斷是否超過陣列長度一半。

Python程式碼:

# -*- coding:utf-8 -*-
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        num = list(set(numbers)) #去重
        count = [] #記錄個數
        for k in range(len(num)):
                 count.append(0)
        for i in range(len(numbers)):
            for j in range(len(count)):
                 if numbers[i] == num[j]:
                     count[j] += 1
        for k in range(len(count)):
            if count[k] > len(numbers)//2:
                 return num[k]
        return 0

思路二

上述做法不是最優演算法,時間複雜度太大了。可用以下思路去做,時間複雜度O(n):

首先,如果存在一個數字出現次數超過陣列長度的一半,那麼它一定比其他所有數字出現的次數都要多。採用陣地攻守的思想:第一個數字作為第一個士兵,守陣地,count = 1;遇到相同元素,count++;遇到不相同元素,即為敵人,同歸於盡,count--;當遇到count為0的情況,又以新的i值作為守陣地的士兵,繼續下去,到最後還留在陣地上的士兵,有可能是主元素。再通過一次迴圈統計出現次數,判斷出現次數是否超過陣列長度的一半。

Python程式碼:

# -*- coding:utf-8 -*-
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        num = numbers[0] #初值為第一個數
        count = 1 #計數
        for i in range(1, len(numbers)):
            # 如果是相同的元素
            if numbers[i] == num:
                count += 1
            else:
                count -= 1
                if count == -1:
                    count = 1
                    num = numbers[i]
        s = 0
        for i in range(0, len(numbers)):
            if numbers[i] == num:
                s += 1
        if s > len(numbers)//2:
            return num
        else:
            return 0