前往
大廳
主題

LeetCode - 1871. Jump Game VII 解題心得

Not In My Back Yard | 2021-07-19 00:00:03 | 巴幣 0 | 人氣 350

題目連結:


題目意譯:
你被給定一個索引值從 0 開始的二元字串 s 以及兩個整數 minJump 以及 maxJump 。一開始,你站在索引值 0 的位置,其值等於 '0'。你可以從索引值 i 移動到索引值 j 如果以下條件滿足:
i + minJump ≦ j ≦ min(i + maxJump, s.length - 1) 且
s[j] == '0'。

回傳真(True)如果可以抵達 s 中的索引值 s.length - 1 之位置;反之,回傳假(False)。

限制:
2 ≦ s.length ≦ 105
s[i] is either '0' or '1'.
s[0] == '0'
1 ≦ minJump ≦ maxJump < s.length



範例測資:
範例 1:
輸入: s = "011010", minJump = 2, maxJump = 3
輸出: true
解釋:
第一步中,從索引值 0 移動到索引值 3 。
第二步中,從索引值 3 移動到索引值 5 。

範例 2:
輸入: s = "01101110", minJump = 2, maxJump = 3
輸出: false


解題思維:
仿照這題,我們從 s 的結尾往回推看是否能從起點到達結尾。當然如果結尾的字元不等於 '0',則我們絕對不可能從起點到達終點(移動到此位置的條件無法滿足)。

我們定義一個陣列 D[i] 代表我們是否能從位置 i 移動到結尾的位置。一開始,很顯然地 D[s.length - 1] = 真。可以看到其他位置 i
如果 D[i + minJump] 、 D[i + minJump + 1] 、 …… 、 D[i + maxJump] 之一為真,則 D[i] 也為真;
反之, D[i] 為假。

因此我們從 i = s.length - minJump - 1 的位置開始(因為可以看到 s.length - minJump 到結尾前一格都無法跳到結尾)維護一個滑動視窗(Sliding Window,其概念曾經出現於這題只是當時沒有提及此名詞)。而該滑動視窗的用意為統計該視窗所涵蓋到的區間有多少位置可到結尾,即對應到 D[i + minJump] + D[i + minJump + 1] + …… + D[i + maxJump] 。

而當視窗的左側往左移動時,內容將變為 D[i + minJump - 1] 、 D[i + minJump + 1] 、 …… 、 D[i + maxJump - 1] ,比起移動前多了 D[i + minJump - 1] 但是少了 D[i + maxJump] (所以可以看到視窗的內容很好更新)。

例如
s = "011010", minJump = 2, maxJump = 3
一開始
s = 011010
D = 000001

然後我們從藍色位置開始往左,而滑動視窗 SW 以橘色表示:
s = 011010
D = 000001
因為 SW 內有位置可以抵達終點且當前位置為 '0',因此
s = 011010
D = 000101

s = 011010
D = 000001
雖然 SW 內有位置可以抵達終點但當前位置為 '1',因此
s = 011010
D = 000101


s = 011010
D = 000001
雖然 SW 內有位置可以抵達終點且當前位置為 '1',因此
s = 011010
D = 000101

s = 011010
D = 000001
因為 SW 內有位置可以抵達終點且當前位置為 '0',因此
s = 011010
D = 100101

因為 D[0] 為真,所以我們可以從起點抵達結尾。而其他的測資也是類似的情形。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作