题目地址:
https://leetcode.com/problems/generalized-abbreviation/
给定一个字符串 s s s,返回其所有可能的缩写。它的缩写的形式是,可以用数字代替连续的若干个字符,但是如果一段子串被数字代替之后,其后的子串就不能用数字代替了。满足上面条件的所有字符串都可以作为缩写。
思路是DFS。开一个StringBuilder名为sb,并从 s [ 0 ] s[0] s[0]开始枚举,枚举其是作为字符存在于缩写中,还是以数字存在于缩写中。如果以字符存在于缩写中,则直接append到sb后面;如果其是以数字存在于缩写中,则枚举其连续多少个字符一起作为数字存在于缩写中。枚举完毕之后,再从下一个没被计入sb的字符位置开始枚举。由于枚举成数字的话,不能连续两段都枚举成数字,所以要开个变量记录一下上次枚举的时候是作为字符还是数字。代码如下:
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<String> generateAbbreviations(String word) {
List<String> res = new ArrayList<>();
dfs(0, false, new StringBuilder(), word, res);
return res;
}
// 从pos开始枚举,prev记录上次枚举的时候是枚举成数字还是字符的
private void dfs(int pos, boolean prev, StringBuilder sb, String word, List<String> res) {
// 枚举到最后一位了,则得到一个合法的缩写,加入res中
if (pos == word.length()) {
res.add(sb.toString());
return;
}
char ch = word.charAt(pos);
sb.append(ch);
dfs(pos + 1, false, sb, word, res);
sb.setLength(sb.length() - 1);
if (!prev) {
for (int j = 1; j + pos <= word.length(); j++) {
sb.append(j);
dfs(j + pos, true, sb, word, res);
sb.setLength(sb.length() - String.valueOf(j).length());
}
}
}
}
时间复杂度为指数级,空间 O ( l s ) O(l_s) O(ls)。