Subsequence With the Minimum Score

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/

posted @ 2023-02-12 22:54  onlyblues  阅读(18)  评论(0编辑  收藏  举报
Web Analytics