LeetCode 2565.最少得分子序列

发布于:2025-09-15 ⋅ 阅读:(16) ⋅ 点赞:(0)

给你两个字符串 s 和 t 。

你可以从字符串 t 中删除任意数目的字符。

如果没有从字符串 t 中删除字符,那么得分为 0 ,否则:

令 left 为删除字符中的最小下标。
令 right 为删除字符中的最大下标。
字符串的得分为 right - left + 1 。

请你返回使 t 成为 s 子序列的最小得分。

一个字符串的 子序列 是从原字符串中删除一些字符后(也可以一个也不删除),剩余字符不改变顺序得到的字符串。(比方说 “ace” 是 “abcde” 的子序列,但是 “aec” 不是)。

示例 1:

输入:s = “abacaba”, t = “bzaa”
输出:1
解释:这个例子中,我们删除下标 1 处的字符 “z” (下标从 0 开始)。
字符串 t 变为 “baa” ,它是字符串 “abacaba” 的子序列,得分为 1 - 1 + 1 = 1 。
1 是能得到的最小得分。
示例 2:

输入:s = “cde”, t = “xyz”
输出:3
解释:这个例子中,我们将下标为 0, 1 和 2 处的字符 “x” ,“y” 和 “z” 删除(下标从 0 开始)。
字符串变成 “” ,它是字符串 “cde” 的子序列,得分为 2 - 0 + 1 = 3 。
3 是能得到的最小得分。

提示:

1 <= s.length, t.length <= 105^55
s 和 t 都只包含小写英文字母。

对于我们要删除的下标,left和right之间的字符可以全部删去,因为越删除,t就越可能成为s的子序列。删除子串后,剩下部分是t的一个前缀和一个后缀,我们可以找到t的后缀能匹配的最长s后缀,可以用suf数组记录下来s的每个下标对应的t中能匹配到的最长后缀,前缀同理,然后找出能使t成为s子序列的最小差值:

class Solution {
public:
    int minimumScore(string s, string t) {
        int sSize = s.size();
        int tSize = t.size();

        int sIdx = sSize - 1;
        int tIdx = tSize - 1;

        // suf保存s的下标最多能匹配到t中哪个后缀
        vector<int> suf(sSize + 1);
        suf[sSize] = tSize;

        while (sIdx >= 0 && tIdx >= 0) {
            if (s[sIdx] == t[tIdx]) {
                --tIdx;
            }

            // 最多能匹配到tIdx+1到t的结尾
            suf[sIdx] = tIdx + 1;
            --sIdx;
        }

        // 如果t匹配完了,说明t本身就是s的子序列
        if (tIdx < 0) {
            return 0;
        }

        // 补全剩下的suf数组
        while (sIdx >= 0) {
            suf[sIdx] = tIdx + 1;
            --sIdx;
        }

        // 初始化为删除t[0:suf[0]]的情况
        int ans = suf[0];
        
        sIdx = 0;
        tIdx = 0;

        while (sIdx < sSize && tIdx < tSize) {
            if (s[sIdx] == t[tIdx]) {
                ++tIdx;
            }

            // 找出最小得分
            // suf[sIdx + 1]是s的下一个下标对应的能匹配的最小right
            // tIdx - 1是s的当前下标对应的能匹配的最大left
            // 能删除的就是(left, right)
            ans = min(ans, suf[sIdx + 1] - (tIdx - 1) - 1);

            ++sIdx;
        }

        return ans;
    }
};

如果s的长度为n,则此算法时间复杂度为O(n),空间复杂度为O(n)。