75100150棧與隊(duì)列

棧篇

題目71:給你一個(gè)字符串?path?,將其轉(zhuǎn)化為更加簡(jiǎn)潔的linux規(guī)范路徑。

思路:因?yàn)樯婕暗椒祷厣弦患?jí)目錄簿训,就要用棧。

題目155:設(shè)計(jì)一個(gè)支持?push?米间,pop?强品,top?操作,并能在常數(shù)時(shí)間內(nèi)檢索到最小元素的棧屈糊。

MinStack()?初始化堆棧對(duì)象的榛。 push(int val)?將元素val推入堆棧。pop()?刪除堆棧頂部的元素逻锐。 top()?獲取堆棧頂部的元素夫晌。 getMin()?獲取堆棧中的最小元素。

思路:既然要按順序保存元素昧诱,那就不能用單調(diào)棧慷丽。那最小元素就用另一個(gè)輔助棧來記錄最小值。

push 入棧的時(shí)候鳄哭,與輔助棧頂?shù)脑乇容^大小要糊,如果小的話,也入輔助棧。pop出棧的時(shí)候锄俄,記得檢查一下是否是最小元素局劲,如果是,輔助棧也要pop奶赠。如果不是鱼填,就不用管。(因?yàn)闂m斣卦谳o助棧那邊也是在最頂?shù)囊愀辏绻皇菞m斣仄煌瑁f明沒有入輔助棧)

題目224:給你一個(gè)只包含 數(shù)字加減括號(hào) 和 空格 的字符串表達(dá)式?s,如:? "(1+(4+5+2)-3)+(6+8)"苇经,請(qǐng)實(shí)現(xiàn)一個(gè)基本計(jì)算器來返回它的值赘理。

思路:1. 首先,要把字符串轉(zhuǎn)變成 符號(hào) 括號(hào) 和 數(shù)字 組成的列表扇单。特別是多位數(shù)字要小心處理商模。

2.? 因?yàn)槔ㄌ?hào)內(nèi)的要先計(jì)算。因此碰到左括號(hào)蜘澜,就先把前面的值和符號(hào)(num, sign)入棧施流,然后初始化num, sign,逐個(gè)加減括號(hào)內(nèi)元素鄙信,得到一個(gè)值瞪醋。碰到右括號(hào)說明括號(hào)內(nèi)計(jì)算完畢,彈出之前的(num, sign)作為 prev_num, prev_sign 装诡,然后 num = prev_num + prev_sign * num

題目394:給定一個(gè)經(jīng)過編碼的字符串银受,返回它解碼后的字符串。如s = "3[a2[c]]"?返回"accaccacc"

思路:多層括號(hào)慎王,務(wù)必手動(dòng)驗(yàn)證一下棧的邏輯蚓土。

由于數(shù)字是乘上其身后括號(hào)里面的字符串。因此可以把已有的字符串和數(shù)字做成元組 (pre_char, num) 放入stack. 直到括號(hào)里面的字符串解碼完畢赖淤,碰到右括號(hào)蜀漆,就彈出(pre_char, num) 用?pre_char + num * (括號(hào)內(nèi)解碼完畢的字符串)

題目735:給定一個(gè)小行星數(shù)組?asteroids,正負(fù)表示移動(dòng)方向咱旱。找出碰撞后剩下的所有小行星确丢。

碰撞規(guī)則:兩個(gè)小行星相互碰撞,較小的小行星會(huì)爆炸吐限。如果兩顆小行星大小相同鲜侥,則兩顆小行星都會(huì)爆炸。

思路:由于有正負(fù)兩個(gè)方向诸典,stack記錄正向移動(dòng)的小行星描函。同時(shí)有可能有一個(gè)負(fù)向移動(dòng)的小行星擊穿所有正向行星,因此還要一個(gè)away來記錄負(fù)向行星。

單調(diào)棧篇

題目901:設(shè)計(jì)一個(gè)算法返回股票當(dāng)日價(jià)格的?跨度?舀寓〉ㄊ跨度?被定義為股票價(jià)格小于或等于今天價(jià)格的最大連續(xù)日數(shù)。例如互墓,如果未來 7 天股票的價(jià)格是?[100,80,60,70,60,75,85]必尼,那么股票跨度將是?[1,1,1,2,1,4,6]?。

實(shí)現(xiàn)?StockSpanner?類:StockSpanner()?初始化類對(duì)象篡撵。int next(int price)?給出今天的股價(jià)?price?判莉,返回該股票當(dāng)日價(jià)格的?跨度?。

思路寫在代碼里了育谬,模擬一遍棧就懂券盅。

隊(duì)列篇

題目933:寫一個(gè)RecentCounter類來計(jì)算特定時(shí)間范圍內(nèi)最近的請(qǐng)求。

RecentCounter()?初始化計(jì)數(shù)器斑司,請(qǐng)求數(shù)為 0 渗饮。int ping(int t)?在時(shí)間?t?添加一個(gè)新請(qǐng)求但汞,并返回在?[t-3000, t]?內(nèi)發(fā)生的請(qǐng)求數(shù)宿刮。

思路:超過3000的請(qǐng)求就要舍棄。先進(jìn)先出私蕾,用隊(duì)列僵缺。每次請(qǐng)求的時(shí)候添加 t ,同時(shí)把超過3000的popleft()踩叭,然后返回隊(duì)列的長(zhǎng)度磕潮。

題目649:Dota2 參議院由D R 兩派的參議員組成。他們按senate的順序逐輪投票容贝。每一位參議員都可以讓另一位參議員在這一輪和隨后的幾輪中喪失?所有的權(quán)利?自脯。宣布勝利:如果參議員發(fā)現(xiàn)有權(quán)利投票的參議員都是?同一個(gè)陣營(yíng)的?,則游戲勝利斤富。

思路:按順序行使權(quán)力膏潮,那最優(yōu)策略就是讓對(duì)方最靠前的那個(gè)參議院失去權(quán)力。因此使用兩個(gè)隊(duì)列满力,分別記錄兩黨參議院的編號(hào)焕参。然后逐對(duì)比較,編號(hào)靠后者失去權(quán)力退出游戲油额。而編號(hào)靠前者加入隊(duì)伍末端叠纷,此時(shí)編號(hào)要加n.

優(yōu)先隊(duì)列/堆 篇

題目215: 給定整數(shù)數(shù)組?nums?和整數(shù)?k,請(qǐng)返回?cái)?shù)組中第?k?個(gè)最大的元素潦嘶。時(shí)間復(fù)雜度為?O(n)?

思路:堆排序的時(shí)間復(fù)雜度是O(nlog(n))涩嚣,所以用堆來實(shí)現(xiàn)O(n)算法有些難度。這里我們假設(shè)k為遠(yuǎn)小于n的數(shù)。那時(shí)間復(fù)雜度還能約等于O(n)

題目502:給你?n?個(gè)項(xiàng)目航厚。對(duì)于每個(gè)項(xiàng)目?i?校摩,它都有一個(gè)純利潤(rùn)?profits[i]?,和啟動(dòng)該項(xiàng)目需要的最小資本?capital[i]?阶淘。最初衙吩,你的資本為?w?。當(dāng)你完成一個(gè)項(xiàng)目時(shí)溪窒,你將獲得純利潤(rùn)坤塞,且利潤(rùn)將被添加到你的總資本中〕喊觯總而言之摹芙,從給定項(xiàng)目中選擇?最多?k?個(gè)不同項(xiàng)目的列表,以?最大化最終資本?宛瞄,并輸出最終可獲得的最多資本浮禾。

思路:本題陷阱很多!首先份汗,把項(xiàng)目按照投資額排序盈电。第二步,由于投資項(xiàng)目個(gè)數(shù)有限杯活,因此每次投資都要拿到最大的利潤(rùn)匆帚。必須用堆!把項(xiàng)目按照利潤(rùn)入最大堆旁钧。然后彈出利潤(rùn)最大的項(xiàng)目吸重,更新本金。循環(huán)k次歪今。

題目373:給定兩個(gè) 非遞減順序排列?的整數(shù)數(shù)組?nums1?和?nums2?,?以及一個(gè)整數(shù)?k?嚎幸。定義一對(duì)值(u,v),其中第一個(gè)元素來自nums1寄猩,第二個(gè)元素來自?nums2?嫉晶。請(qǐng)找到和最小的?k個(gè)數(shù)對(duì)(u1,v1),?(u2,v2)?...(uk,vk)。

思路:i, j 是nums1 nums2 中的索引, i, j 都有可能取到很大焦影。但全部?jī)蓛上嗉尤ヅ判蛱速M(fèi)時(shí)間復(fù)雜度车遂。(i+1, j+1) 能夠取到的先決條件是(i+1, j)和 (i, j+1)都被取到了。那就可以用類似動(dòng)態(tài)規(guī)劃的思路斯辰,i 為行舶担,j為列。

初始化就把第一行 nums1[0] + nums2[j] 都加入最小堆彬呻。每次從最小堆中取出一對(duì)數(shù)組衣陶,然后加入下一行的元素nums1[i+1] + nums2[j]柄瑰。列取到 j ,意味著下一行的元素nums1[i+1] + nums2[k] k<j 都已經(jīng)塞進(jìn)去了剪况,不會(huì)遺漏教沾。

題目295:求取數(shù)據(jù)流的中位數(shù)。實(shí)現(xiàn) MedianFinder 類: MedianFinder() 初始化?MedianFinder對(duì)象译断。void addNum(int num)?將數(shù)據(jù)流中的整數(shù)?num?添加到數(shù)據(jù)結(jié)構(gòu)中授翻。double findMedian()?返回到目前為止所有元素的中位數(shù)。與實(shí)際答案相差10-5以內(nèi)的答案將被接受孙咪。

思路:用兩個(gè)堆來實(shí)現(xiàn)堪唐。用最小堆存放數(shù)據(jù)流中的較大一半元素;用最大堆存放數(shù)據(jù)流中的較小 一半元素翎蹈。兩個(gè)堆形成上下對(duì)稱的兩個(gè)倒三角淮菠。三角塔尖就是中位數(shù)。

添加元素的時(shí)候荤堪,必須在兩個(gè)堆中都遍歷一遍合陵,才能保證上三角的元素都大于下三角。

題目2336:實(shí)現(xiàn)?SmallestInfiniteSet?類:SmallestInfiniteSet()?初始化:無限集包含所有正整數(shù)澄阳。int popSmallest()?移除并返回該無限集中的最小整數(shù)拥知。void addBack(int num)?如果正整數(shù)?num?不?存在于無限集中,則將一個(gè)?num?添加?到該無限集最后寇荧。

肯定不可能真的實(shí)現(xiàn)無限集合举庶,那就看功能执隧,滿足功能的要求即可揩抡。

思路:取正整數(shù)的最小值嘛,那肯定從1開始取镀琉。如果沒有中途添加元素峦嗤,那就每次按照一個(gè)順序 self.smallest 1 2 3 ...這樣返回即可。如果有添加過元素屋摔,那就看取出來的按原定順序取出來的元素self.smallest還是中途添加的元素烁设,如果是中途添加的元素,self.smallest不用+1. 同時(shí)在添加過的元素集合self.added_set中丟去這個(gè)中途添加的元素钓试。

中途添加元素的功能装黑,如果比當(dāng)前的最小整數(shù)self.smallest大,就根本不用添加弓熏。如果小的話恋谭,就看有沒有在添加過的元素集合self.added_set中,不在挽鞠,就加入最小堆疚颊。

思路:使用排序的集合狈孔。由于pop()功能做多用1000次,那就給一個(gè)包含[1, 1001]的排列集合就好材义。每次取最小均抽,就把第一個(gè)元素丟出來。添加元素的話其掂,集合隨意添加油挥,還帶排序。

題目2542:兩個(gè)長(zhǎng)度為n的整數(shù)數(shù)組nums1和nums2款熬。選擇長(zhǎng)度為 k 的 子序列喘漏,使得:(nums1[i0] + nums1[i1] +...+ nums1[ik - 1]) * min(nums2[i0] , nums2[i1], ... ,nums2[ik - 1]) 最大。

思路:由于在nums2中华烟,我們?nèi)〉氖亲钚≈掉媛酢D蔷涂梢园凑課ums2排序,先取到第k個(gè)值盔夜,此時(shí)的nums2[k]就是最小值负饲,然后乘上nums1的累加和,算出得分喂链。然后繼續(xù)向前遍歷返十,pop掉nums1值最小的那一對(duì),加入新的nums2椭微。如果新的得分更大洞坑,就更新。

題目2462:給定整數(shù)數(shù)組costs和兩個(gè)整數(shù)k?和candidates蝇率。costs[i]是雇傭第?i位工人的成本迟杂。總共進(jìn)行k輪雇傭本慕,且每一輪恰好雇傭一位工人排拷。在每一輪雇傭中,從最前面?candidates和最后面?candidates人中選出成本最小的一位工人锅尘,如果有多位代價(jià)相同且最小的工人监氢,選擇下標(biāo)更小的一位工人。返回雇傭k位工人的總代價(jià)藤违。

思路:“如果有多位代價(jià)相同且最小的工人浪腐,選擇下標(biāo)更小的一位工人” 那這就簡(jiǎn)單了。每一輪將left, right范圍內(nèi)的工人和下標(biāo)丟進(jìn)一個(gè)最小堆顿乒,每次取出一個(gè)议街。然后根據(jù)下表確定范圍是在left 還是在right 變化

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市淆游,隨后出現(xiàn)的幾起案子傍睹,更是在濱河造成了極大的恐慌隔盛,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拾稳,死亡現(xiàn)場(chǎng)離奇詭異吮炕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)访得,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門龙亲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人悍抑,你說我怎么就攤上這事鳄炉。” “怎么了搜骡?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵拂盯,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我记靡,道長(zhǎng)谈竿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任摸吠,我火速辦了婚禮空凸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寸痢。我一直安慰自己呀洲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布啼止。 她就那樣靜靜地躺著道逗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪族壳。 梳的紋絲不亂的頭發(fā)上憔辫,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音仿荆,去河邊找鬼。 笑死坏平,一個(gè)胖子當(dāng)著我的面吹牛拢操,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播舶替,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼令境,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了顾瞪?” 一聲冷哼從身側(cè)響起舔庶,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤抛蚁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后惕橙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瞧甩,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年弥鹦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肚逸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡彬坏,死狀恐怖朦促,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情栓始,我是刑警寧澤务冕,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站幻赚,受9級(jí)特大地震影響洒疚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坯屿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一油湖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧领跛,春花似錦乏德、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至矢棚,卻和暖如春郑什,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蒲肋。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來泰國打工蘑拯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人兜粘。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓申窘,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親孔轴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子剃法,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容