溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

LeetCode如何找出數(shù)組中出現(xiàn)次數(shù)超過(guò)一半的數(shù)字

發(fā)布時(shí)間:2021-12-15 14:18:27 來(lái)源:億速云 閱讀:145 作者:小新 欄目:大數(shù)據(jù)

這篇文章主要為大家展示了“LeetCode如何找出數(shù)組中出現(xiàn)次數(shù)超過(guò)一半的數(shù)字”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“LeetCode如何找出數(shù)組中出現(xiàn)次數(shù)超過(guò)一半的數(shù)字”這篇文章吧。

題目描述

數(shù)組中有一個(gè)數(shù)字出現(xiàn)的次數(shù)超過(guò)數(shù)組長(zhǎng)度的一半,請(qǐng)找出這個(gè)數(shù)字。

你可以假設(shè)數(shù)組是非空的,并且給定的數(shù)組總是存在多數(shù)元素。

1 <= 數(shù)組長(zhǎng)度 <= 50000

       

題目樣例

       

示例

輸入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 輸出: 2

       

題目思考

  1. 如何不使用額外空間?
  2. 如果題目不保證一定存在多數(shù)元素又該怎么辦?
       

解決方案

       
思路
  • 一個(gè)最簡(jiǎn)單的思路是用一個(gè)計(jì)數(shù)字典存每個(gè)數(shù)字的出現(xiàn)次數(shù), 找最大的那個(gè)即可, 但這需要額外的空間, 不是面試官心目中的理想答案
  • 重新分析題目, 某個(gè)數(shù)字出現(xiàn)超過(guò)一半, 那意味著其他數(shù)字的數(shù)目之和都小于它, 如果我們將這些 不同數(shù)字進(jìn)行兩兩抵消, 那么最后剩余的那個(gè)數(shù)字一定是超過(guò)一半的那個(gè)數(shù)字, 這就引出了下面的思路:
    1. 維護(hù)一個(gè)當(dāng)前候選者, 以及當(dāng)前它的計(jì)數(shù), 初始化就是數(shù)組頭一個(gè)數(shù)字, 計(jì)數(shù)為 1
    2. 從第二個(gè)數(shù)字開始遍歷數(shù)組, 如果當(dāng)前數(shù)字等于候選者, 那么計(jì)數(shù)值加 1, 否則就減 1 表示抵消了一個(gè)數(shù)字
    3. 如果此時(shí)計(jì)數(shù)小于 0 的話, 就說(shuō)明之前的候選者這個(gè)時(shí)候要被淘汰了, 因?yàn)樗呀?jīng)被抵消光了. 所以就重新選擇當(dāng)前的數(shù)字作為新的候選者, 同時(shí)重置計(jì)數(shù)值為 1.
    4. 這樣最后剩余的那個(gè)候選者一定是最終結(jié)果, 因?yàn)榇祟}的前提是一定存在這樣的數(shù)字
  • 當(dāng)然, 如果題目不保證一定存在多數(shù)元素, 那么我們?cè)诘玫阶罱K候選者之后, 需要重新遍歷一遍數(shù)組并累加其計(jì)數(shù), 確保其計(jì)數(shù)超過(guò)一半, 不然的話就說(shuō)明整個(gè)數(shù)組沒有多數(shù)元素. 例如數(shù)組 [1,2,3], 利用此方法得到的最終候選者為 3, 但它并不是多數(shù)元素, 只是恰好最后一個(gè)被選出來(lái)的候選者而已.
       
復(fù)雜度
  • 時(shí)間復(fù)雜度 O(N)
    • 只需要遍歷數(shù)組一遍
  • 空間復(fù)雜度 O(1)
    • 只使用了幾個(gè)變量
       
代碼
class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        # 初始化候選者和計(jì)數(shù)
        res = nums[0]
        cnt = 1
        for x in nums[1:]:
            if x == res:
                # 當(dāng)前元素等于候選者, 計(jì)數(shù)值+1
                cnt += 1
            else:
                # 否則計(jì)數(shù)值-1
                cnt -= 1
                if cnt < 0:
                    # 如果計(jì)數(shù)值小于0的話, 就說(shuō)明之前保存的候選者現(xiàn)在被淘汰了, 將當(dāng)前元素變?yōu)樾碌暮蜻x者, 并重置計(jì)數(shù)值為1
                    res = x
                    cnt = 1
        return res

以上是“LeetCode如何找出數(shù)組中出現(xiàn)次數(shù)超過(guò)一半的數(shù)字”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI