Subsequence With the Minimum Score
You are given two strings $s$ and $t$ .
You are allowed to remove any number of characters from the string t.
The score string is $0$ if no characters are removed from the string $t$, otherwise:
- Let left be the minimum index among all removed characters.
- Let right be the maximum index among all removed characters.
Then the score of the string is right - left + 1 .
Return the minimum possible score to make $t$ a subsequence of $s$.
A subsequence of a string is a new string that is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (i.e., "ace" is a subsequence of "abcde" while "aec" is not).
Example 1:
Input: s = "abacaba", t = "bzaa" Output: 1 Explanation: In this example, we remove the character "z" at index 1 (0-indexed). The string t becomes "baa" which is a subsequence of the string "abacaba" and the score is 1 - 1 + 1 = 1. It can be proven that 1 is the minimum score that we can achieve.
Example 2:
Input: s = "cde", t = "xyz" Output: 3 Explanation: In this example, we remove characters "x", "y" and "z" at indices 0, 1, and 2 (0-indexed). The string t becomes "" which is a subsequence of the string "cde" and the score is 2 - 0 + 1 = 3. It can be proven that 3 is the minimum score that we can achieve.
Constraints:
- $1 \leq \text{s.length}, \text{t.length} \leq {10}^5$
- $s$ and $t$ consist of only lowercase English letters.
解题思路
今天不知道为什么状态突然变得这么差,刚刚的cf也炸了。
首先如果答案是$r - l + 1$,那么意味着至少要删除$t[r]$和$t[l]$才能与$s$匹配,由于答案已经固定了,因此贪心地想到可以把$t[l \sim r]$都删掉,一样可以与$s$匹配,保证正确性。因此问题就变成了删除$t$的一个连续的子串,使得$t$是$s$子串。
假设最小答案是$\text{ans}$,那么很明显如果删除的长度超过$\text{ans}$,$t$一样是$s$的子串,因此可以二分答案。
假设删除的连续子串长度为$\text{mid}$,那么在$\text{check}$函数中枚举要删除的连续子串$t[l \sim r]$,看一下$t[1 \sim l-1]$和$t[r+1 \sim n]$是否是$s$的子串并且没有重叠的部分。如果直接暴力枚举的话那么$\text{check}$函数的时间复杂度是$O(n^2)$。因此看一下能不能通过预处理来把判断的部分优化到$O(1)$。
由于$t[1 \sim l-1]$和$t[r+1 \sim n]$分别是$t$的前缀和后缀,因此可以通过前后缀分解来预处理出来两个数组。其中$f[i]$表从$s$的前缀开始匹配,$t[1 \sim i]$是$s$的子串的最小的下标。$g[i]$表从$s$的后缀开始匹配,$t[i \sim n]$是$s$的子串的最大的下标。
因此在$\text{check}$中如果$f[i] \ne +\infty$并且$g[r+1] \ne -\infty$并且$f[l-1] < g[r+1]$,则表示可以通过删除长度为$\text{mid}$的连续子串使得$t$是$s$的子串。
AC代码如下:
1 class Solution { 2 public: 3 int minimumScore(string s, string t) { 4 int n = s.size(), m = t.size(); 5 vector<int> f(m + 1, n + 1), g(m + 2, 0); 6 f[0] = 0, g[m + 1] = n + 1; 7 for (int i = 1, j = 1; i <= n; i++) { 8 if (j <= m && s[i - 1] == t[j - 1]) f[j++] = i; 9 } 10 for (int i = n, j = m; i; i--) { 11 if (j && s[i - 1] == t[j - 1]) g[j--] = i; 12 } 13 int l = 0, r = m; 14 function<bool(int)> check = [&](int len) { 15 for (int i = 1; i + len - 1 <= m; i++) { 16 if (f[i - 1] < g[i + len]) return true; 17 } 18 return false; 19 }; 20 while (l < r) { 21 int mid = l + r >> 1; 22 if (check(mid)) r = mid; 23 else l = mid + 1; 24 } 25 return l; 26 } 27 };
参考资料
前后缀 & 二分:https://leetcode.cn/problems/subsequence-with-the-minimum-score/solution/qian-hou-zhui-er-fen-by-tsreaper-hdd3/
标签:子串,string,text,Score,Subsequence,Minimum,characters,score,sim From: https://www.cnblogs.com/onlyblues/p/17114927.html