1. 程式人生 > >【劍指offer】陣列中出現次數超過陣列長度一半的數字(三種解法)

【劍指offer】陣列中出現次數超過陣列長度一半的數字(三種解法)

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

如果使用時間複雜度為O(n),可以構建hash map,但是應該會存在衝突,並且要設計資料結構
在python3中,如果要讓map輸出list,在前面要加list,要不然只會返回一個地址

hashList = list(map(hash, [-1.1, -2.6, -2.6, 0, 1, 2]))
print(hashList)
>>>> [-230584300921369601
, -1383505805528216578, -1383505805528216578, 0, 1, 2]

解法1

class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        if numbers == []:
            return 0
        dictonary = {}
        dictonary = dictonary.fromkeys(numbers, 0)
        for num in numbers:
            dictonary[
num] += 1 for key in dictonary.keys(): if dictonary[key] * 2 > len(numbers): return key return 0

執行時間:29ms

佔用記憶體:5736k

解法2

在上一篇部落格中,知道了如何找出陣列中第k大個數字。地址:找出陣列中任意第k大的數字
如果一個數字的個數超過半數,那麼第N/2大的數字一定是這個數字,因此用這個方法找出第N/2大的數字,然後判斷這個數字的出現次數是不是滿足大於長度的二分之一。(N為陣列的長度)

class
Solution: def partitionOfK(self, numbers, start, end, k): if k < 0 or numbers == [] or start < 0 or end >= len(numbers) or k > end: return None low = start high = end key = numbers[start] while low < high: while low < high and numbers[high] >= key: high -= 1 numbers[low] = numbers[high] while low < high and numbers[low] <= key: low += 1 numbers[high] = numbers[low] numbers[low] = key if low < k: return self.partitionOfK(numbers, start + 1, end, k) elif low > k: return self.partitionOfK(numbers, start, end - 1, k) else: return numbers[low] def checkMoreThanHalf(self, numbers, num): times = 0 for number in numbers: if num == number: times += 1 if times * 2 <= len(numbers): return False return True def MoreThanHalfNum_Solution(self, numbers): # write code here if numbers == []: return 0 result = self.partitionOfK(numbers, 0, len(numbers) - 1, len(numbers) >> 2) if self.checkMoreThanHalf(numbers, result): return result else: return 0

執行時間:35ms

佔用記憶體:5728k

解法3

陣列中如果有一個數字出現的次數超過陣列長度的一半,也就是說他出現的次數比其他所有的數字出現的次數的和還要多。因此當我們遍歷到下一個數字的時候,如果相同,次數加一,不同次數減一,直到0。如果為0,那麼儲存下一個數字,並把次數設定為1,找的就是最後設定為1的數字

class Solution:
    def checkMoreThanHalf(self, numbers, num):
        times = 0
        for number in numbers:
            if num == number:
                times += 1
        if times * 2 <= len(numbers):
            return False
        return True
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        if numbers == []:
            return 0
        result = numbers[0]
        times = 1
        for i in range(1, len(numbers)):
            if times == 0:
                result = numbers[i]
                times = 1
            elif numbers[i] == result:
                times += 1
            else:
                times -= 1
        if self.checkMoreThanHalf(numbers, result):
            return result
        else:
            return 0

執行時間:25ms

佔用記憶體:5856k

相關推薦

offer---數組出現次數超過一半數字

不同的 div 基礎 還要 否則 ret break temp tor (註意到目標數 超過數組長度的一半,對數組同時去掉兩個不同的數字,到最後剩下的一個數就是該數字。如果剩下兩個,那麽這兩個也是一樣的,就是結果),在其基礎上把最後剩下的一個數字或者兩個回到原來數組中,將

1-offer: 數組出現次數超過一半數字

vector 兩個 dex 如果 num 輸入 index 不存在 lse 題目描述 數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度為9的數組{1,2,3,2,2,2,5,4,2}。由於數字2在數組中出現了5次,超過數組長度的一半,因此輸出2

offer陣列出現次數超過陣列長度一半數字解法

題目描述 陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。如果不存在則輸出0。 如果使用時間複雜度為O(n),可以構建

offer整數1出現次數從1到n整數1出現次數

題目描述 求出1~13的整數中1出現的次數,並算出100~1300的整數中1出現的次數?為此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,但是對於後面問題他就沒轍了。ACMer希望你們幫幫他,並把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數(從1

offer 面試題4 二維陣列的查詢

題目: 在一個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下的遞增的順序排序,請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。 解題思路 關鍵是,我們從哪裡開始查詢? 如果是從頭開始查,那麼所查之數比陣列當前遍歷元素大的話,我們怎

offer整數1出現次數

題目描述:親們!!我們的外國友人YZ這幾天總是睡不好,初中奧數裡有一個題目一直困擾著他,特此他向JOBDU發來求助信,希望親們能幫幫他。問題是:求出1~13的整數中1出現的次數,並算出100~1300的整數中1出現的次數?為此他特別數了一下1~13中包含1的數字有1、10、1

offer圓圈最後剩下的數字,C++實現

一行 AC 個人 ron namespace itl i++ float color 原創博文,轉載請註明出處! # 題目 # 思路 本題即為典型的約瑟夫問題,通過遞推公式解決。 第一行表示每個人的下標,現在要從11個人中刪除報數為3的人,從圖

offer二進位制1的個數java

問題描述:輸入一個二進位制數,我們記為num,計算出num中有幾個1,結果用count儲存 思路分析:如二進位制數11011,將其減1,得11010,再與原來的數做與運算 11011&11010,得11010,此二進位制數相比原二進位制數,數中的1少了一個。重複此過程,直至該數變為0

offer序列的某一位數字

題目描述 數字以01234567891011121314…的格式序列化到一個字元序列中,在這個序列中,從0開始數,第5位是5,第13位是1,第19位是4,等等,請寫一個函式,求任意第n位對應的數字。 求出每一位對應的數字總和,然後判斷。注意邊界條件不好處理時,可以採用while true

offer矩陣的路徑回溯法

# -*- coding:utf-8 -*- class Solution: def hasPathCore(self, matrix, rows, cols, row, col, path,

Offer面試題8:旋轉陣列的最小數字

一:題目描述 把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。 輸入一個非遞減排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。 例如陣列{3,4,5,1,2}為{1,2,3,4,5}的一個旋轉,該陣列的最小值為1。 NOTE:給出的所有元素都大於0,若陣列大

offer面試題21:調整陣列順序使奇數位於偶數前面

題目1:輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有奇數位於陣列的前半部分,所有偶數位於陣列的後半部分。 如果不考慮時間複雜度,最簡單的思路應該是從頭掃描這個陣列,每碰到一個偶數時,拿出這個數字,並把位於這個數字後面的所有的數字往前面挪動一位。挪完之後在陣列的末

offer面試題39陣列出現次數超過陣列長度一半數字

方法1: 從數學角度看,所求的數一定的原陣列(有序化)的中位數,那麼,我們可以通過對陣列排序,這樣得到的時間複雜度是O(nlogn)O(nlogn)。而如果能夠優化到在O(n)O(n)的時間內找到,就更好了。基於快速排序的partition階段,如果我們可以

offer陣列出現次數超過陣列長度一半的數。

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

Offer二進位制1的個數

題目描述 輸入一個整數,輸出該數二進位制表示中1的個數。其中負數用補碼錶示。 補碼 解題前,我們先來了解一下補碼。在計算機系統中,數值都是用補碼來表示和儲存的。 而原碼就是數值的二進位制數表示,最高位1表示負數。 以32位數值舉例 1的原碼就是 -1的原碼就是 正數的補碼等於原碼 負數的補碼等於其原碼

offer面試題 57:和為 S 的數字

題目描述 輸入一個遞增排序的陣列和一個數字S,在陣列中查詢兩個數,是的他們的和正好是S,如果有多對數字的和等於S,輸出兩個數的乘積最小的。 輸出描述: 對應每個測試案例,輸出兩個數,小的先輸出。

Offer6、旋轉數組的最小數字

length num 旋轉 是的 一次 排序數組 ray 技術 處理 ??題目描述: ??把一個數組最開始的若幹個元素搬到數組的末尾,我們稱之為數組的旋轉。 輸入一個非減排序的數組的一個旋轉,輸出旋轉數組的最小元素。 例如數組{3,4,5,1,2}為{1,2,3,4,5}的

java 找到陣列出現次數超過陣列長度一半的那個數字

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

Offer26陣列出現次數超過一半數字

題目描述 陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。如果不存在則輸出0。 時間限制:1秒;空間限制:32768K;本題知識點:陣列 解題思路

Java offer(39) 陣列出現次數超過一半數字Offer》Java實現合集 《Offer》Java實現合集

本文參考自《劍指offer》一書,程式碼採用Java語言。 更多:《劍指Offer》Java實現合集   題目    陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入一個長度為9的陣列{1, 2, 3, 2, 2, 2, 5, 4, 2}。由於數字2在陣列中出現