形成字符串的最短路径
难度:
标签:
题目描述
代码结果
运行时间: 38 ms, 内存: 16.1 MB
/*
* Problem 1055: Shortest Way to Form String
*
* Given a string source and a string target, return the minimum number of subsequences of source such that their concatenation equals target.
* If the task is impossible, return -1.
*
* Approach using Java Streams:
* 1. Stream through the target string and try to match characters in the source using IntStream.
* 2. Use nested IntStream loops to check for character matches.
* 3. Return -1 if no progress is made in matching.
*/
import java.util.stream.IntStream;
public class Solution {
public int shortestWay(String source, String target) {
int[] result = {0}; // To store number of subsequences used
int i = 0; // Pointer for target
while (i < target.length()) {
int start = i; // To track progress in target
i = IntStream.range(i, target.length())
.filter(idx -> IntStream.range(0, source.length())
.anyMatch(j -> source.charAt(j) == target.charAt(idx)))
.findFirst()
.orElse(target.length());
if (start == i) { // No progress in target
return -1;
}
result[0]++;
}
return result[0];
}
}
解释
方法:
该题解利用了一个贪心算法的思想,主要目标是使用给定的source字符串尽可能多地形成target字符串。首先,创建一个字典dic,里面包含26个空列表,分别对应26个字母的索引。遍历source字符串,将每个字符的索引按字母顺序存储到相应的列表中。对于target中的每个字符,如果在source中找不到该字符,则直接返回-1,表示无法形成。如果找到了,使用二分搜索来寻找可以接上的最小的索引。如果找到了更大的索引,就继续;如果没有找到,表示当前source的遍历已经结束,需要重新开始遍历source,此时计数器ans加1。最后,返回使用source字符串形成target所需的最少次数。
时间复杂度:
O(n + m*log(n))
空间复杂度:
O(n)
代码细节讲解
🦆
在构建索引列表时,你选择了一个包含26个空列表的字典来存储字符索引。请问为什么选择这种数据结构而不是其他类型的数据结构?
▷🦆
在遍历target字符串时,你使用了二分搜索来查找可以接上的最小的索引。请问在这里使用二分搜索的具体原因是什么?
▷🦆
你提到如果在遍历target时,没有找到合适的索引就需要重新从source的开始位置进行遍历,这个过程是如何确保总体最短路径的?
▷相关问题
判断子序列
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"
是"abcde"
的一个子序列,而"aec"
不是)。
进阶:
如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
致谢:
特别感谢 @pbrother 添加此问题并且创建所有测试用例。
示例 1:
输入:s = "abc", t = "ahbgdc" 输出:true
示例 2:
输入:s = "axc", t = "ahbgdc" 输出:false
提示:
0 <= s.length <= 100
0 <= t.length <= 10^4
- 两个字符串都只由小写字符组成。