最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

【算法題】一題四解!力扣第 1562 題 - 查找大小為 M 的最新分組 - Scala 和 C# 題解

2022-08-25 23:24 作者:ZeromaX訸  | 我要投稿


今天做力扣學(xué)習(xí)計劃的“二分查找基礎(chǔ)”的時候,碰到一道有意思的題目:1562. 查找大小為 M 的最新分組?,可以使用四種不同的思路(單調(diào)棧、模擬、二分查找、并查集)進(jìn)行解答,非常適合學(xué)習(xí)與練習(xí),在此給大家分享一下。

話說最近一直沒有更新文章,主要就是因為力扣上面不小心開了好幾個學(xué)習(xí)計劃同時進(jìn)行,一天得寫十幾道題,都快寫吐了。不過這周估計可以全部解決掉,以后再也不這樣搞了。主要都是中等和簡單題,新手用來學(xué)習(xí)不錯,我這樣刷起來有點費時間了。(不過倒是順便練了練 Kotlin 和 C#)

如果你要練學(xué)習(xí)計劃的話,可以提醒一下,其實當(dāng)天沒寫完也是可以的,可以后面補(bǔ)(如果到了時間還沒寫完那就不知道是否可以了),而且可以提前寫后面未解鎖的題目,提交通過的話,后面也是不需要重復(fù)寫的。

1 題目

1562. 查找大小為 M 的最新分組 難度:中等

給你一個數(shù)組 arr ,該數(shù)組表示一個從 1n 的數(shù)字排列。有一個長度為 n 的二進(jìn)制字符串,該字符串上的所有位最初都設(shè)置為 0 。

在從 1n 的每個步驟 i 中(假設(shè)二進(jìn)制字符串和 arr 都是從 1 開始索引的情況下),二進(jìn)制字符串上位于位置 arr[i] 的位將會設(shè)為 1 。

給你一個整數(shù) m ,請你找出二進(jìn)制字符串上存在長度為 m 的一組 1 的最后步驟。一組 1 是一個連續(xù)的、由 1 組成的子串,且左右兩邊不再有可以延伸的 1 。

返回存在長度 恰好m一組 1 ?的最后步驟。如果不存在這樣的步驟,請返回 -1 。

示例 1

輸入:arr?=?[3,5,1,2,4],?m?=?1
輸出:4
解釋
步驟?1:"00100",由?1?構(gòu)成的組:["1"]
步驟?2:"00101",由?1?構(gòu)成的組:["1",?"1"]
步驟?3:"10101",由?1?構(gòu)成的組:["1",?"1",?"1"]
步驟?4:"11101",由?1?構(gòu)成的組:["111",?"1"]
步驟?5:"11111",由?1?構(gòu)成的組:["11111"]
存在長度為?1?的一組?1?的最后步驟是步驟?4?。

示例 2

輸入:arr?=?[3,1,5,4,2],?m?=?2
輸出:-1
解釋
步驟?1:"00100",由?1?構(gòu)成的組:["1"]
步驟?2:"10100",由?1?構(gòu)成的組:["1",?"1"]
步驟?3:"10101",由?1?構(gòu)成的組:["1",?"1",?"1"]
步驟?4:"10111",由?1?構(gòu)成的組:["1",?"111"]
步驟?5:"11111",由?1?構(gòu)成的組:["11111"]
不管是哪一步驟都無法形成長度為?2?的一組?1?。

示例 3

輸入:arr?=?[1],?m?=?1
輸出:1

示例 4

輸入:arr?=?[2,1],?m?=?2
輸出:2


提示

  • n == arr.length

  • 1 <= n <= 10^5

  • 1 <= arr[i] <= n

  • arr 中的所有整數(shù) 互不相同

  • 1 <= m <= arr.length

來源:力扣(LeetCode)
鏈接:https://leetcode.cn/problems/find-latest-group-of-size-m
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有。商業(yè)轉(zhuǎn)載請聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

2 時間順序單調(diào)棧法

首先介紹一個相對冷門的單調(diào)棧的題解:https://leetcode.cn/problems/find-latest-group-of-size-m/solution/er-fen-zhen-bu-shou-huan-shi-dan-diao-zh-375g/,感覺這個思路確實和其他模擬思路題解相比挺新穎的,除了這一篇,基本就沒有提到的了。只是原題解代碼寫的有點冗雜了,遮蔽了其思路主旨。我使用 Scala 一邊重構(gòu)了一下代碼,一邊理解思路,終于看懂了。感覺最后的成品代碼更方便大家理解,就也分享一下吧~ (用 C# 也補(bǔ)了一份實現(xiàn),方便熟悉 C++ 或 Java 的同學(xué)閱讀)

具體思路可以參考注釋,還是不懂的話,大致介紹一下:

  • 首先將 arr 處理為存儲對應(yīng)索引的 1 的插入時間的數(shù)組 t。這里有個特殊處理的 t[0]t[arr.length + 1] 取值 Int 最大值,簡化后續(xù)處理。

  • 然后按照時間順序遞增(對應(yīng)變量 i,范圍為 [0, arr.length + 1])檢查單調(diào)棧,如果棧里非空且 t[棧頂] < t[i] 說明在 i 左側(cè)的 1 插入時間早于 i 處的 1,所以我們就可以把這個連接在一起的時間點算出來。我們的目的是找到最晚的一個連接長度為 m 的時間點。

  • 長度就是對應(yīng) i - 下一個棧頂 - 1,因為下一個棧頂?shù)挠覀?cè)就是相當(dāng)于當(dāng)前連接的全 1 序列最左端。當(dāng)長度等于 m 時我們可以計算出來目前全 1 序列首次出現(xiàn)的時間,即 t[下一個棧頂], t[i] 的最小值

  • 重復(fù)以上邏輯就可以將最大的結(jié)果找出來。

看懂了就不禁感嘆:“妙啊,妙啊……”,只是理解起來沒有模擬始末節(jié)點數(shù)組法直觀。代碼如下:

Scala

C#


3 模擬始末節(jié)點數(shù)組法

給官方題解的方法起了一個這個名字,感覺應(yīng)該比較好理解吧。具體原理可以看 官方題解:https://leetcode.cn/problems/find-latest-group-of-size-m/solution/cha-zhao-da-xiao-wei-m-de-zui-xin-fen-zu-by-leetco/,Scala 的實現(xiàn)的話直接看代碼吧:


4 題外話

這道題目我是從“二分查找基礎(chǔ)”的學(xué)習(xí)計劃過來的,但是包括官方題解在內(nèi)的大多數(shù)題解沒用到二分查找,真是笑死……

順便提一下,其實是有二分查找的思路的,具體來說就是對應(yīng)這篇 Java 用到了 TreeSet 的題解:https://leetcode.cn/problems/find-latest-group-of-size-m/solution/fan-xiang-qjing-wei-shen-sui-ran-wo-yun-xing-shi-j/ 以及這篇 C++ 用到了 set 的題解:https://leetcode.cn/problems/find-latest-group-of-size-m/solution/zheng-xiang-si-wei-by-sui-xin-yuan-oaiv/ ,逆向從全 1 的時間往回查的思路也還是挺妙的。我就先懶得自己用 Scala 試了,看懂單調(diào)棧的那篇原題解耗費太多腦細(xì)胞,讓我緩緩。(笑)

另外,其實并查集顯然也可以做,合并集合(全為 1 的序列)并計數(shù)統(tǒng)計集合大小,典型并查集題目嘛。并查集不清楚的話,可以參考上面 C++二分的那篇題解,也提到了并查集。(其實我自己首先想到就是這個思路,但自己是二分查找進(jìn)來的,就感覺套并查集套模板有點沒意思了,后來就看題解去看二分咋寫了。看到逆向基本就懂了二分是啥思路,就感覺沒啥必要自己寫了,就去學(xué)習(xí)前面分享的這兩種寫法了)

順便分享一下自己簡單的并查集的 Java、Scala、Kotlin 模板吧,套起來用還是很方便的:

Java

Scala

Kotlin



【算法題】一題四解!力扣第 1562 題 - 查找大小為 M 的最新分組 - Scala 和 C# 題解的評論 (共 條)

分享到微博請遵守國家法律
辽中县| 拉孜县| 清流县| 清远市| 河津市| 灵台县| 资兴市| 宝兴县| 安福县| 铁岭市| 黄梅县| 濮阳市| 虞城县| 封丘县| 巨野县| 宜阳县| 平阴县| 崇信县| 大同县| 黔东| 禹城市| 荥阳市| 封丘县| 南岸区| 浦北县| 疏勒县| 浦城县| 柞水县| 康平县| 宁城县| 鄯善县| 徐州市| 双牌县| 林甸县| 长垣县| 邵武市| 湘乡市| 肃宁县| 铜川市| 兴宁市| 乌海市|