1. 程式人生 > 其它 >LeetCode1208. 儘可能使字串相等(滑動視窗)

LeetCode1208. 儘可能使字串相等(滑動視窗)

技術標籤:String滑動視窗

1、題目描述

https://leetcode-cn.com/problems/get-equal-substrings-within-budget/

給你兩個長度相同的字串,s 和 t。只含小寫英文字母。

  • 將 s中的第i個字元變到t中的第 i 個字元需要|s[i] - t[i]|的開銷(開銷可能為 0),也就是兩個字元的 ASCII 碼值的差的絕對值。
  • 用於變更字串的最大預算是maxCost。在轉化字串時,總開銷應當小於等於該預算,這也意味著字串的轉化可能是不完全的。

如果你可以將 s 的子字串轉化為它在 t 中對應的子字串,則返回可以轉化的最大長度

如果 s 中沒有子字串可以轉化成 t 中對應的子字串,則返回 0。

輸入:s = "abcd", t = "bcdf", cost = 3
輸出:3
解釋:s 中的 "abc" 可以變為 "bcd"。開銷為 3,所以最大長度為 3。
輸入:s = "abcd", t = "cdef", cost = 3
輸出:1
解釋:s 中的任一字元要想變成 t 中對應的字元,其開銷都是 2。因此,最大長度為 1。
輸入:s = "abcd", t = "acde", cost = 0
輸出:1
解釋:你無法作出任何改動,所以最大長度為 1。

2、程式碼詳解

滑動視窗移動的思路:

  • 以右指標作為驅動,拖著左指標向前走。右指標每次只移動一步,而左指標在內部 while 迴圈中每次可能移動多步。
  • 右指標是主動前移,探索未知的新區域;左指標是被迫移動,負責尋找滿足題意的區間。

模板修改之處:

  1. 模板中的 sums需要根據題目意思具體去修改,本題是求和題目因此把sums 定義成整數用於求和;如果是計數題目,就需要改成字典用於計數。當左右指標發生變化的時候,都需要更新 sums。
  2. 需要根據題目去修改的是內層 while 迴圈的判斷條件,即: 區間[left, right]不符合題意 。對於本題而言,就是該區內的和 sums超過了 maxCost。
def findSubArray(nums):
    N = len(nums) # 陣列/字串長度
    left, right = 0, 0 # 雙指標,表示當前遍歷的區間[left, right],閉區間
    sums = 0 # 用於統計 子陣列/子區間 是否有效,根據題目可能會改成求和/計數
    res = 0 # 儲存最大的滿足題目要求的 子陣列/子串 長度
    while right < N: # 當右邊的指標沒有搜尋到 陣列/字串 的結尾
        sums += nums[right] # 增加當前右邊指標的數字/字元的求和/計數
        while 區間[left, right]不符合題意:# 此時需要一直移動左指標,直至找到一個符合題意的區間
            sums -= nums[left] # 移動左指標前需要從counter中減少left位置字元的求和/計數
            left += 1 # 真正的移動左指標,注意不能跟上面一行程式碼寫反
        # 到 while 結束時,我們找到了一個符合題意要求的 子陣列/子串
        res = max(res, right - left + 1) # 需要更新結果
        right += 1 # 移動右指標,去探索新的區間
    return res

程式碼如下:

class Solution:
    def equalSubstring(self, s: str, t: str, maxCost: int) -> int:
        n = len(s)
        costs = [0] * n
        for i in range(n):
            costs[i] = abs(ord(s[i]) - ord(t[i]))
        left = 0
        right = 0

        sums = 0  # 用於統計 子陣列/子區間 是否有效
        res = 0  # 儲存最大的滿足題目要求的 子陣列/子串 長度

        while right < n:
            sums += costs[right]
            while sums > maxCost:
                sums -= costs[left]
                left += 1
            res = max(res, right - left + 1)
            right += 1
        return res

https://leetcode-cn.com/problems/get-equal-substrings-within-budget/solution/fen-xiang-zhen-cang-de-hua-dong-chuang-k-e3rd/