题目地址:
https://leetcode.com/problems/stamping-the-sequence/description/
给定两个字符串 p , s p,s p,s,给出一个与 s s s等长的空格串,每次允许将其某一长与 p p p长度相等的一段变为 p p p(可以覆盖之前的操作),问最后能否将其变为 s s s。要求返回一个方案,方案里为每次操作的起点下标。
由于后面的操作可以覆盖之前的,可以将所有的操作倒过来看,那么问题就变为从 s s s出发,每次可以将这样的一段变为空格,该段满足:将该段去掉空格,并且将 p p p的对应位置也变为空格,两个串就相等了。问是否最后能变为空格串。这个可以直接模拟,每次暴力枚举 s s s的与 p p p长度相等的一段串 t t t,如果 t t t与 p p p的对应位置匹配(要么相等,要么 t t t在那个位置为空格),那么就将 t t t整个变为空格。如果最后可以得到空格串,则说明方案存在,最后的方案需要将操作下标逆序返回。如果得不到空格串,则说明无解。代码如下:
class Solution {
public:
vector<int> movesToStamp(string stamp, string s) {
vector<int> res;
bool can_do = true;
while (can_do) {
can_do = false;
for (int i = 0; i + stamp.size() <= s.size(); i++)
if (work(stamp, s, i)) {
can_do = true;
res.push_back(i);
}
}
if (s != string(s.size(), '?')) return {};
reverse(res.begin(), res.end());
return res;
}
bool work(string& p, string& s, int i) {
if (s.substr(i, p.size()) == string(p.size(), '?')) return false;
for (int k = 0; k < p.size(); k++)
if (s[i + k] != p[k] && s[i + k] != '?')
return false;
for (int k = 0; k < p.size(); k++)
s[i + k] = '?';
return true;
}
};
时间复杂度 O ( l s 2 l p ) O(l_s^2l_p) O(ls2lp),空间 O ( 1 ) 。 O(1)。 O(1)。