题目大意:
形成字符串的最短路径
对于任何字符串,我们可以通过删除其中一些字符(也可能不删除)来构造该字符串的子序列。
给定源字符串 source 和目标字符串 target,找出源字符串中能通过串联形成目标字符串的子序列的最小数量。如果无法通过串联源字符串中的子序列来构造目标字符串,则返回 -1。
示例 1:
输入:source = "abc", target = "abcbc" 输出:2 解释:目标字符串 "abcbc" 可以由 "abc" 和 "bc" 形成,它们都是源字符串 "abc" 的子序列。
示例 2:
输入:source = "abc", target = "acdbc" 输出:-1 解释:由于目标字符串中包含字符 "d",所以无法由源字符串的子序列构建目标字符串。
示例 3:
输入:source = "xyz", target = "xzyxz" 输出:3 解释:目标字符串可以按如下方式构建: "xz" + "y" + "xz"。
提示:
source和target两个字符串都只包含 “a”-“z” 的英文小写字母。source和target两个字符串的长度介于1和1000之间。
如果想查看本题目是哪家公司的面试题,请参考以下免费链接: https://leetcode.jp/problemdetail.php?id=1055
解题思路分析:
本题需要先对source字符串进行预处理,我们统计出2组信息,第一,字符串中每种字符首次出现的下标(没出现过的字符默认为-1)。第二,统计出每个下标后面距离它最近的a-z分别在哪里。
接下来我们先查看target的首字符在 source 中首次出现的位置sIndex,如果是-1,说明该字符不在 target 中,返回-1。如果存在,我们循环到target的下一位字符c,并且查看距离 sIndex 最近的字符c的位置,如果存在继续循环。反之如果不存在,说明当前子序列已经不能再继续下去,需要重头开始寻找新的子序列,此时返回结果加一,并且查看当前字符c在 source 中首次出现的位置,将该位置赋值给 sIndex ,继续重复上述操作,直到循环完 target 中所有字符为止。
实现代码:
public int shortestWay(String source, String target) {
// 保存source中每种字符首次出现的位置
int[] firstIndex=new int[26];
// 默认是-1(-1代表没出现过)
Arrays.fill(firstIndex, -1);
// 保存source字符串每个下标右侧距离他最近的a-z的位置
int[][] nextMap = new int[source.length()][26];
// 从后向前循环source每个字符
for(int i=source.length()-1;i>=0;i--){
if(i<source.length()-1){
// 赋值后一行信息后一行
nextMap[i]=Arrays.copyOf(nextMap[i+1],26);
// 后一个字符的位置为i+1
nextMap[i][source.charAt(i+1)-'a']=i+1;
}
// 更新当前字符首次出现位置
firstIndex[source.charAt(i)-'a']=i;
}
int res=1; // 返回结果
// target首字符在source中首次出现的位置
int sIndex=firstIndex[target.charAt(0)-'a'];
// 如果为-1,表示不存在,返回-1
if(sIndex==-1) return -1;
// 循环target的每个字符
for(int i=1;i<target.length();i++){
// 当前字符
int c = target.charAt(i)-'a';
// 查看source中距离下标sIndex最近的字符c的位置
sIndex=nextMap[sIndex][c];
// 如果为0,说明sIndex后不再存在该字符c,当前子序列结束
if(sIndex==0){
// 返回结果加一
res++;
// 查看当前字符在source中首次出现的位置
sIndex=firstIndex[c];
// 如果为-1,表示不存在,返回-1
if(sIndex==-1) return -1;
}
}
return res;
} 本题解法执行时间为2ms。
Runtime: 2 ms, faster than 85.60% of Java online submissions for Shortest Way to Form String.
Memory Usage: 41 MB, less than 50.00% of Java online submissions for Shortest Way to Form String.
本网站文章均为原创内容,并可随意转载,但请标明本文链接如有任何疑问可在文章底部留言。为了防止恶意评论,本博客现已开启留言审核功能。但是博主会在后台第一时间看到您的留言,并会在第一时间对您的留言进行回复!欢迎交流!
本文链接: http://leetcode.jp/leetcode-1055-shortest-way-to-form-string-解题思路分析/