前往
大廳
主題

LeetCode - 1898. Maximum Number of Removable Characters 解題心得

Not In My Back Yard | 2021-09-28 00:00:10 | 巴幣 0 | 人氣 227

題目連結:


題目意譯:
你被給定兩字串 s 和 p ,其中 p 為 s 的一個子序列。你同時也被給定一個索引值從 0 開始之相異整數陣列 removable 其包含著 s 的索引值之一個子集合(s 的索引值也是從 0 開始)。

你想要選擇一整數 k (0 ≦ k ≦ removable.length)使得將 removable 前 k 個儲存的索引值對應的 s 中之 k 個字元移除後, p 依舊是 s 的一個子序列。更正式地說,你將標記字元 s[removable[i]] 對於 0 ≦ i < k,然後移除掉所有被標記的字元,然後檢查 p 是否仍是一個子序列。

回傳你最大能選擇的 k 值,使得移除字元後 p 依然是 s 的一個子序列。

一字串的一個子序列為一個新字串其由刪除若干個(可以沒有)原字串中的字元並保持剩餘字元之間的相對順序而產生。

限制:
1 ≦ p.length ≦ s.length ≦ 10 ^ 5
0 ≦ removable.length < s.length
0 ≦ removable[i] < s.length
p 為 s 的一個子序列。
s 和 p 皆由小寫英文字母組成。
removable 中的元素皆相異。



範例測資:
範例 1:
輸入: s = "abcacb", p = "ab", removable = [3,1,0]
輸出: 2
解釋: 移除掉索引值 3 和 1 的字元後,"abcacb" 變為 "accb" 。
"ab" 為 "accb" 的一個子序列。
如果我們移除掉索引值 3 、 1 和 0 的字元,"abcacb" 變為 "ccb",而 "ab" 不再是一個子序列。
因此,最大的 k 值為 2。

範例 2:
輸入: s = "abcbddddd", p = "abcd", removable = [3,2,1,4,5,6]
輸出: 1
解釋: 移除掉索引值 3 的字元後,"abcbddddd" 變成 "abcddddd" 。
"abcd" 為 "abcbddddd" 的一個子序列。

範例 3:
輸入: s = "abcab", p = "abc", removable = [0,1,2,3,4]
輸出: 0
解釋: 如果移除掉陣列 removable 中的第一個索引值,"abc" 將不再是一個子序列。


解題思維:
假設我們已經知道怎麼檢查一字串是否為另一字串的子序列(如這題),則我們可以套用二分搜尋法(Binary Search)來找到所求的最大 k 值。

因為我們可以看到對於所有可能的 k 值,其會有下列現象:
p 是子序列、
p 是子序列、
……、
p 不再是子序列、
p 不是子序列
……
中間會有一個「斷層」(如這題)。所以我們才可以使用二分搜。

令下界 L = 0 、 上界 U = removable.length,重複以下步驟直到 L = U 為止:
令 M = ceil(L + U) ÷ 2 ,其中 ceil() 為上高斯函數,對正數來說為無條件進位至整數。然後檢查 p 是否為子序列,在檢查過程中忽視掉 remoable 前 M 個標記的 s 之字元。如果依舊是子序列的話,我們便可以將下界提高至 L = M;反之,我們將上界降低至 U = M - 1。

最後的 L 之值即為所求最大 k 值。




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

創作回應

更多創作