原题说明
From any string, we can form a subsequence of that string by deleting some number of characters (possibly no deletions).
Given two strings source and target, return the minimum number of subsequences of source such that their concatenation equals target. If the task is impossible, return -1.
Example 1:
Input: source = “abc”, target = “abcbc”
Output: 2
Explanation: The target “abcbc” can be formed by “abc” and “bc”, which are subsequences of source “abc”.
Example 2:
Input: source = “abc”, target = “acdbc”
Output: -1
Explanation: The target string cannot be constructed from the subsequences of source string due to the character “d” in target string.
Example 3:
Input: source = “xyz”, target = “xzyxz”
Output: 3
Explanation: The target string can be constructed as follows “xz” + “y” + “xz”.
Constraints:
- Both the
sourceandtargetstrings consist of only lowercase English letters from “a”-“z”. - The lengths of
sourceandtargetstring are between1and1000.
解题思路
O(MN)的解法较为直观,只需要用两个index i和j分别对应source和target的位置,然后对于每一个target[j],在source中找到对应的source[i], 并于每次i归零时计数即可。
这里介绍O(M + N)的解法:用一个二维哈希表(或者二维数组)index_to_next来表示当前source的index右边(包括index本身), 每一个字母第一次出现的位置的下一个位置。比如abbc,那么index[0]['a'] = 1, index[0]['b'] = 2, index[1]['b'] = 2, index[2]['b'] = 3...
从右向左遍历一遍source即可完成更新index_to_next, 然后遍历target,source和target的位置分别记为i和j,我们执行以下操作:
index_to_next[0]当中是否存在target[j],即整个source中是否存在j,不存在则返回-1index_to_next[i]当中是否存在target[j],如果不存在,说明source在位置i右侧不存在target[j],i应当归零从头开始找- 如果
i == 0,说明source被遍历了一边,返回值round应该增加1 - 更新
i = index_to_next[i][target[i]]即source中i右侧第一个target[j]的右侧的位置,这样相当于在source中读取了一个最近的target[i]
最后返回round即可。
示例代码 (cpp)
1 | class Solution { |
示例代码 (java)
1 | public int shortestWay(String source, String target) { |
示例代码 (python)
1 | # two pointer greedy O(MN) |
复杂度分析
时间复杂度: O(M + N)
空间复杂度: O(M)
归纳总结
我们在Youtube上更新了视频讲解,欢迎关注!