劍指offer第二版(Python3)--面試題39 : 數組中出現次數超過一半的數字

第2章 面試需要的基礎知識

第3章 高質量的代碼

第4章 解決面試題的思路

  面試題27:二叉樹的鏡像

  面試題29:順時針打印矩陣

  面試題30 :包含min函數的棧

  面試題31:棧的壓入、彈出序列

  面試題32:上往下打印二叉樹

  面試題33: 二叉搜索樹的後序遍歷序列

  面試題34: 二叉樹中和爲某一值的路徑

  面試題35:複雜鏈表的複製

  面試題36:二叉搜索樹與雙向鏈表

  面試題38:字符串的排列

第5章 優化時間和空間效率

第6章 面試中的各項能力

第7章 兩個面試案例


題目描述

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

解題思路
牛客網
方法一:
  數組中有一個數字出現的次數超過數組長度的一半,所以它出現的次數比其它數出現的次數總和還多。考慮在遍歷數組時保存兩個值:一個是數組中的一個數字,另一個是次數。
  當我們遍歷到下一個數字時,如果下一個數字和我們之前保存的數字相同,則次數加1;如果不同,則次數減1。如果次數爲零,則需要保存下一個數字,並把次數設爲1。這樣要找的數字可能是最後一次把次數設爲1時對應的數字,還需要統計這個數字在數組中的數量才能確認。
實戰

class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        length = len(numbers)
        i = 0
        counts = 0
        while i < length:
            if counts == 0:
                digit = numbers[i]
                i += 1
                counts = 1
                continue
            if numbers[i] != digit:
                counts -= 1
            else:
                counts += 1
            i += 1
        
        counts = 0
        for num in numbers:
            if num == digit:
                counts += 1
        if counts > length >> 1:
            return digit
        return 0

方法二:
  受快速排序啓發,有成熟的得到數組中任意第k大數字的算法,且時間複雜度爲O(n)。如果數組有一個數其數量超過數組長度一半,那麼排序後的數組其中間位置的數一定就是那個次數超過一半的數,所以這道題可以引申爲尋找排序數組的中間位置數。
  我們先隨機選取一個數字,然後調整數組順序,使得比選中數字大的數在其右邊,小的數在其左邊。如果選中的數其索引恰好爲n/2,則這個數就是中間位置數;如果其索引大於n/2,那麼中間位置數在這個數的左邊,然後繼續去左邊數組中查找;否則中間位置數在其右邊,繼續去右邊數組中查找。這是一個典型的遞歸過程。
實戰

class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        if not numbers:
            return numbers
        
        def recc(begin, end):
            if begin >= end:
                return numbers[begin]
            index = begin
            for i in range(begin+1, end+1):
                if numbers[index] > numbers[i]:
                    numbers[index], numbers[i] = numbers[i], numbers[index]
                    index = i 
            if index == length >> 1:
                return numbers[index]
            if index > length >> 1:
                num = recc(begin, index-1)
            else:
                num = recc(index+1, end)
            return num
        
        length = len(numbers)
        number = recc(0, length-1)
        counts = 0
        for i in range(length):
            if number == numbers[i]:
                counts += 1
        if counts > length >> 1:
            return number
        return 0
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章