RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀(guān)看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何解決數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)最大頻率棧問(wèn)題?

算法與數(shù)據(jù)結(jié)構(gòu) ? 來(lái)源:labuladong ? 作者:labuladong ? 2021-03-02 11:02 ? 次閱讀

讀完本文,可以去力扣解決如下題目:

895.最大頻率棧(Hard)

我個(gè)人很喜歡設(shè)計(jì)特殊數(shù)據(jù)結(jié)構(gòu)的問(wèn)題,畢竟在工作中會(huì)經(jīng)常用到基本數(shù)據(jù)結(jié)構(gòu),而設(shè)計(jì)類(lèi)的問(wèn)題就非??简?yàn)對(duì)基本數(shù)據(jù)結(jié)構(gòu)的理解和運(yùn)用。

力扣第 895 題要求我們實(shí)現(xiàn)一個(gè)特殊的數(shù)據(jù)結(jié)構(gòu)「最大頻率?!?,比較有意思,讓我們實(shí)現(xiàn)下面這兩個(gè) API

class FreqStack {

// 在棧中加入一個(gè)元素 val

public void push(int val) {}

// 從棧中刪除并返回出現(xiàn)頻率最高的元素

// 如果頻率最高的元素不止一個(gè),

// 則返回最近添加的那個(gè)元素

public int pop() {}

}

比如下面這個(gè)例子:

FreqStack stk = new FreqStack();

// 向最大頻率棧中添加元素

stk.push(2); stk.push(7); stk.push(2);

stk.push(7); stk.push(2); stk.push(4);

// 棧中元素:[2,7,2,7,2,4]

stk.pop() // 返回 2

// 因?yàn)?2 出現(xiàn)了三次

// 棧中元素:[2,7,2,7,4]

stk.pop() // 返回 7

// 2 和 7 都出現(xiàn)了兩次,但 7 是最近添加的

// 棧中元素:[2,7,2,4]

stk.pop() // 返回 2

// 棧中元素:[2,7,4]

stk.pop() // 返回 4

// 棧中元素:[2,7]

這種設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)的問(wèn)題,主要是要搞清楚問(wèn)題的難點(diǎn)在哪里,然后結(jié)合各種基本數(shù)據(jù)結(jié)構(gòu)的特性,高效實(shí)現(xiàn)題目要求的 API。

那么,我們仔細(xì)思考一下 push 和 pop 方法,難點(diǎn)如下:

1、每次 pop 時(shí),必須要知道頻率最高的元素是什么。

2、如果頻率最高的元素有多個(gè),還得知道哪個(gè)是最近 push 進(jìn)來(lái)的元素是哪個(gè)。

為了實(shí)現(xiàn)上述難點(diǎn),我們要做到以下幾點(diǎn):

1、肯定要有一個(gè)變量 maxFreq 記錄當(dāng)前棧中最高的頻率是多少。

2、我們得知道一個(gè)頻率 freq 對(duì)應(yīng)的元素有哪些,且這些元素要有時(shí)間順序。

3、隨著 pop 的調(diào)用,每個(gè) val 對(duì)應(yīng)的頻率會(huì)變化,所以還得維持一個(gè)映射記錄每個(gè) val 對(duì)應(yīng)的 freq。

綜上,我們可以先實(shí)現(xiàn) FreqStack 所需的數(shù)據(jù)結(jié)構(gòu):

class FreqStack {

// 記錄 FreqStack 中元素的最大頻率

int maxFreq = 0;

// 記錄 FreqStack 中每個(gè) val 對(duì)應(yīng)的出現(xiàn)頻率,后文就稱(chēng)為 VF 表

HashMap《Integer, Integer》 valToFreq = new HashMap《》();

// 記錄頻率 freq 對(duì)應(yīng)的 val 列表,后文就稱(chēng)為 FV 表

HashMap《Integer, Stack《Integer》》 freqToVals = new HashMap《》();

}

其實(shí)這有點(diǎn)類(lèi)似前文 手把手實(shí)現(xiàn) LFU 算法,注意 freqToVals 中 val 列表用一個(gè)棧實(shí)現(xiàn),如果一個(gè) freq 對(duì)應(yīng)的元素有多個(gè),根據(jù)棧的特點(diǎn),可以首先取出最近添加的元素。

要記住在 push 和 pop 方法中同時(shí)修改 maxFreq、VF 表、FV 表,否則容易出現(xiàn) bug。

現(xiàn)在,我們可以來(lái)實(shí)現(xiàn) push 方法了:

public void push(int val) {

// 修改 VF 表:val 對(duì)應(yīng)的 freq 加一

int freq = valToFreq.getOrDefault(val, 0) + 1;

valToFreq.put(val, freq);

// 修改 FV 表:在 freq 對(duì)應(yīng)的列表加上 val

freqToVals.putIfAbsent(freq, new Stack《》());

freqToVals.get(freq).push(val);

// 更新 maxFreq

maxFreq = Math.max(maxFreq, freq);

}

pop 方法的實(shí)現(xiàn)也非常簡(jiǎn)單:

public int pop() {

// 修改 FV 表:pop 出一個(gè) maxFreq 對(duì)應(yīng)的元素 v

Stack《Integer》 vals = freqToVals.get(maxFreq);

int v = vals.pop();

// 修改 VF 表:v 對(duì)應(yīng)的 freq 減一

int freq = valToFreq.get(v) - 1;

valToFreq.put(v, freq);

// 更新 maxFreq

if (vals.isEmpty()) {

// 如果 maxFreq 對(duì)應(yīng)的元素空了

maxFreq--;

}

return v;

}

這樣,兩個(gè) API 都實(shí)現(xiàn)了,算法執(zhí)行過(guò)程如下:

嗯,這道題就解決了,Hard 難度的題目也不過(guò)如此嘛~

原文標(biāo)題:數(shù)據(jù)結(jié)構(gòu)基本功:設(shè)計(jì)最大頻率棧

文章出處:【微信公眾號(hào):算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7002

    瀏覽量

    88940
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1499

    瀏覽量

    61959

原文標(biāo)題:數(shù)據(jù)結(jié)構(gòu)基本功:設(shè)計(jì)最大頻率棧

文章出處:【微信號(hào):TheAlgorithm,微信公眾號(hào):算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    視覺(jué)軟件HALCON的數(shù)據(jù)結(jié)構(gòu)

    在研究機(jī)器視覺(jué)算法之前,我們需要先了解機(jī)器視覺(jué)應(yīng)用中涉及的基本數(shù)據(jù)結(jié)構(gòu)。Halcon數(shù)據(jù)結(jié)構(gòu)主要有圖像參數(shù)和控制參數(shù)兩類(lèi)參數(shù)。圖像參數(shù)包括:image、region、XLD,控制參數(shù)包括:string、integer、real、handle、tuple數(shù)組等。
    的頭像 發(fā)表于 11-14 10:20 ?342次閱讀
    視覺(jué)軟件HALCON的<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>

    永磁發(fā)電機(jī)的主要結(jié)構(gòu)設(shè)計(jì)是什么?

    永磁發(fā)電機(jī)是一種利用永磁體產(chǎn)生磁場(chǎng)的發(fā)電機(jī),它具有結(jié)構(gòu)簡(jiǎn)單、體積小、重量輕、效率高、維護(hù)方便等優(yōu)點(diǎn)。永磁發(fā)電機(jī)的主要結(jié)構(gòu)設(shè)計(jì)包括以下幾個(gè)方面: 定子部分 定子是發(fā)電機(jī)的核心部件之一,它主要由定子鐵芯
    的頭像 發(fā)表于 10-25 10:40 ?200次閱讀

    架構(gòu)師日記-從數(shù)據(jù)庫(kù)發(fā)展歷程到數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)探析

    數(shù)據(jù)庫(kù)發(fā)展史 起初,數(shù)據(jù)的管理方式是文件系統(tǒng),數(shù)據(jù)存儲(chǔ)在文件中,數(shù)據(jù)管理和維護(hù)都由程序員完成。后來(lái)發(fā)展出樹(shù)形結(jié)構(gòu)和網(wǎng)狀
    的頭像 發(fā)表于 09-25 11:20 ?792次閱讀
    架構(gòu)師日記-從<b class='flag-5'>數(shù)據(jù)</b>庫(kù)發(fā)展歷程到<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)</b>探析

    嵌入式常用數(shù)據(jù)結(jié)構(gòu)有哪些

    在嵌入式編程中,數(shù)據(jù)結(jié)構(gòu)的選擇和使用對(duì)于程序的性能、內(nèi)存管理以及開(kāi)發(fā)效率都具有重要影響。嵌入式系統(tǒng)由于資源受限(如處理器速度、內(nèi)存大小等),因此對(duì)數(shù)據(jù)結(jié)構(gòu)的選擇和使用尤為關(guān)鍵。以下是嵌入式編程中常用的幾種數(shù)據(jù)結(jié)構(gòu),結(jié)合具體特點(diǎn)和
    的頭像 發(fā)表于 09-02 15:25 ?461次閱讀

    EMC(電磁兼容性)結(jié)構(gòu)設(shè)計(jì)基礎(chǔ)

    介紹了電磁兼容的基本定義,要求,結(jié)構(gòu)設(shè)計(jì)的準(zhǔn)則和方法。
    發(fā)表于 08-08 14:23 ?13次下載

    5針M16接口結(jié)構(gòu)設(shè)計(jì)

    德索工程師說(shuō)道5針M16接口的結(jié)構(gòu)設(shè)計(jì)是一個(gè)綜合性的過(guò)程,它融合了電氣、機(jī)械、材料科學(xué)等多個(gè)領(lǐng)域的知識(shí),旨在提供高效、穩(wěn)定且可靠的電氣連接。以下是對(duì)5針M16接口結(jié)構(gòu)設(shè)計(jì)的詳細(xì)解析:   5針
    的頭像 發(fā)表于 08-03 09:38 ?404次閱讀
    5針M16接口<b class='flag-5'>結(jié)構(gòu)設(shè)計(jì)</b>

    3針M5插座結(jié)構(gòu)設(shè)計(jì)

       德索工程師說(shuō)道在電子設(shè)備和電氣系統(tǒng)中,插座作為連接電源、信號(hào)線(xiàn)等的重要接口,其結(jié)構(gòu)設(shè)計(jì)對(duì)于設(shè)備的整體性能、穩(wěn)定性和安全性具有至關(guān)重要的作用。3針M5插座作為其中一種常見(jiàn)的插座類(lèi)型,其設(shè)計(jì)不僅
    的頭像 發(fā)表于 05-11 17:49 ?495次閱讀
    3針M5插座<b class='flag-5'>結(jié)構(gòu)設(shè)計(jì)</b>

    FPGA設(shè)計(jì)中,對(duì)SPI進(jìn)行參數(shù)化結(jié)構(gòu)設(shè)計(jì)

    今天給大俠帶來(lái)FPGA設(shè)計(jì)中,對(duì)SPI進(jìn)行參數(shù)化結(jié)構(gòu)設(shè)計(jì),話(huà)不多說(shuō),上貨。 為了避免每次SPI驅(qū)動(dòng)重寫(xiě),直接參數(shù)化,盡量一勞永逸。SPI master有啥用呢,你發(fā)現(xiàn)各種外圍芯片的配置一般
    發(fā)表于 05-07 16:09

    7芯M9插頭需采用彈性結(jié)構(gòu)設(shè)計(jì)

    德索工程師說(shuō)道彈性結(jié)構(gòu)設(shè)計(jì)可以確保7芯M9插頭與插座之間的良好接觸。在插頭插入插座的過(guò)程中,由于制造公差、使用環(huán)境等因素的影響,插頭與插座之間的接觸并不總是完美的。而彈性結(jié)構(gòu)設(shè)計(jì)可以通過(guò)其自身的彈性
    的頭像 發(fā)表于 04-18 14:29 ?373次閱讀
    7芯M9插頭需采用彈性<b class='flag-5'>結(jié)構(gòu)設(shè)計(jì)</b>嗎

    探索編程世界的七大數(shù)據(jù)結(jié)構(gòu)

    樹(shù)結(jié)構(gòu)就像是一顆倒掛的小樹(shù),有根、有枝、有葉。它是一種非線(xiàn)性的數(shù)據(jù)結(jié)構(gòu),以層級(jí)的方式存儲(chǔ)數(shù)據(jù),頂部是根節(jié)點(diǎn),底部是葉節(jié)點(diǎn)。
    的頭像 發(fā)表于 04-16 12:04 ?385次閱讀

    FPGA設(shè)計(jì)中,對(duì)SPI進(jìn)行參數(shù)化結(jié)構(gòu)設(shè)計(jì)

    今天給大俠帶來(lái)FPGA設(shè)計(jì)中,對(duì)SPI進(jìn)行參數(shù)化結(jié)構(gòu)設(shè)計(jì),話(huà)不多說(shuō),上貨。 為了避免每次SPI驅(qū)動(dòng)重寫(xiě),直接參數(shù)化,盡量一勞永逸。SPI master有啥用呢,你發(fā)現(xiàn)各種外圍芯片的配置一般
    發(fā)表于 04-11 18:29

    TASKING編譯器是否可以將數(shù)據(jù)結(jié)構(gòu)設(shè)置為 \"打包\"?

    TASKING 編譯器是否可以將數(shù)據(jù)結(jié)構(gòu)設(shè)置為 \"打包\"? GCC 很早以前就提供了這種可能性,可以將__attribute__((packed))與對(duì)齊指令結(jié)合使用。 對(duì)于
    發(fā)表于 03-05 06:00

    矢量與柵格數(shù)據(jù)結(jié)構(gòu)各有什么特征

    矢量數(shù)據(jù)結(jié)構(gòu)和柵格數(shù)據(jù)結(jié)構(gòu)是地理信息系統(tǒng)(GIS)中最常用的兩種數(shù)據(jù)結(jié)構(gòu)。它們?cè)诖鎯?chǔ)和表示地理要素上有著不同的方法和特征。在接下來(lái)的文章中,我們將詳細(xì)介紹這兩種數(shù)據(jù)結(jié)構(gòu)并比較它們的特點(diǎn)
    的頭像 發(fā)表于 02-25 15:06 ?2531次閱讀

    異步FIFO結(jié)構(gòu)設(shè)計(jì)

    電子發(fā)燒友網(wǎng)站提供《異步FIFO結(jié)構(gòu)設(shè)計(jì).pdf》資料免費(fèi)下載
    發(fā)表于 02-06 09:06 ?0次下載

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之跳表詳解

    大家好,今天分享一篇C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)相關(guān)的文章--跳表。
    的頭像 發(fā)表于 12-29 09:32 ?824次閱讀
    C語(yǔ)言<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>之跳表詳解
    RM新时代网站-首页