题目链接
有重复字符串的排列组合
题目描述
注意点
- 字符都是英文字母
- 字符串长度在[1, 9]之间
解答思路
- 本题与无重复字符串的排列组合类似,区别是字符串中有重复字符,所以组合数量不会是固定的n * (n - 1) * (n - 2) * … * 1
- 首先想到的仍然是深度优先遍历,区别是结果集中同一个位置相同的字符只能添加一次(字符可能在s的不同位置),所以可以使用map存储每个字符和字符的出现次数,对每个位置需要加入的字符可以遍历map的key集合,每个位置能否加入字符c可以根据上一次dfs传入的map.get©判断是否还有剩余的c可以使用
代码
class Solution {
int n;
public String[] permutation(String s) {
n = s.length();
List<String> list = new ArrayList<>();
Map<Character, Integer> map = new HashMap<>();
for (char c : s.toCharArray()) {
map.put(c, map.getOrDefault(c, 0) + 1);
}
dfs(s, 0, map, new StringBuilder(), list);
return list.toArray(new String[list.size()]);
}
public void dfs(String s, int depth, Map<Character, Integer> map, StringBuilder sonRes, List<String> list) {
if (depth >= n) {
list.add(sonRes.toString());
return;
}
for (Character c : map.keySet()) {
if (map.get(c) == 0) {
continue;
}
sonRes.append(c);
map.put(c, map.get(c) - 1);
dfs(s, depth + 1, map, sonRes, list);
sonRes.deleteCharAt(sonRes.length() - 1);
map.put(c, map.get(c) + 1);
}
}
}
关键点
- 深度优先遍历的思想
- 保证结果集中每个位置相同的字符只会考虑一次