你想要用小写字母组成一个目标字符串 target。
开始的时候,序列由 target.length 个 '?' 记号组成。而你有一个小写字母印章 stamp。
在每个回合,你可以将印章放在序列上,并将序列中的每个字母替换为印章上的相应字母。你最多可以进行 10 * target.length 个回合。
举个例子,如果初始序列为 "?????",而你的印章 stamp 是 "abc",那么在第一回合,你可以得到 "abc??"、"?abc?"、"??abc"。(请注意,印章必须完全包含在序列的边界内才能盖下去。)
如果可以印出序列,那么返回一个数组,该数组由每个回合中被印下的最左边字母的索引组成。如果不能印出序列,就返回一个空数组。
例如,如果序列是 "ababc",印章是 "abc",那么我们就可以返回与操作 "?????" -> "abc??" -> "ababc" 相对应的答案 [0, 2];
另外,如果可以印出序列,那么需要保证可以在 10 * target.length 个回合内完成。任何超过此数字的答案将不被接受。
示例 1:
输入:stamp = "abc", target = "ababc"
输出:[0,2]
([1,0,2] 以及其他一些可能的结果也将作为答案被接受)
示例 2:
输入:stamp = "abca", target = "aabcaca"
输出:[3,0,1]
提示:
1 <= stamp.length <= target.length <= 1000
stamp 和 target 只包含小写字母。
思路:我们可以倒着思考问题,假如说最终是可以印出来目标数组的,则最后一个印章的位置是不会被覆盖的,我们考虑当前最后一次印章的位置,从它开始和stamp数组进行比较,如果相等,则将他们替换成‘?’,然后将数组按照该位置分成两部分,再查找这两部分分别最后一次印章的位置,并比较(要注意这里的比较中是含有‘?’,而‘?’是可以和任意字符匹配的哦),由于问题已经分解为两个子问题了,剩下的就是采取和第一次相同的步骤而已。
class Solution {
private boolean flag;
public int[] movesToStamp(String stamp, String target) {
flag=false;
List<Integer> list=new ArrayList<>();
list=work(0,stamp,target);
if(flag) return new int[0];
int[] arr=new int[list.size()];
for(int i=0;i<list.size();i++)
arr[i]=list.get(i);
return arr;
}
private List<Integer> work(int index,String a,String b){
if(b.length()<a.length() || !jud(b) || flag)
return new ArrayList<>();
boolean mark=false;
List<Integer> res=new ArrayList<>();
for(int i=0;i<b.length();i++) {
if(i+a.length()>b.length())
break;
if(!jud(b.substring(i, i+a.length())))
continue;
if(check(b.substring(i, i+a.length()),a)) {
mark=true;
StringBuilder tmp=new StringBuilder(b.substring(0, i));
for(int j=0;j<a.length();j++)
tmp.append('?');
tmp.append(b.substring(i+a.length()));
res.addAll(work(index,a,tmp.toString().substring(0, i+a.length()-1)));
res.addAll(work(index+i+1,a,tmp.toString().substring(i+1)));
res.add(index+i);
break;
}
}
if(!mark) flag=true;
return res;
}
private boolean jud(String a) {
for(int i=0;i<a.length();i++) {
if(a.charAt(i)!='?')
return true;
}
return false;
}
private boolean check(String a,String b) {
for(int i=0;i<a.length();i++) {
if(a.charAt(i)!=b.charAt(i) && a.charAt(i)!='?')
return false;
}
return true;
}
}