leetcode-剑指offer【38】-字符串的排列
[博客链接]
[题目描述]
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:
输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]
限制:
1 <= s 的长度 <= 8
Related Topics 回溯算法
👍 297 👎 0
[题目链接]
[github地址]
[思路介绍]
思路一:暴力法+递归+回溯
- 每个字符串一个选择状态,
- 通过回溯进行递归字符串拼接
- 然后放入set中最后返回不含相同元素的String数组
class Solution{
Set<String> set = new HashSet<>();
public String[] permutation(String s) {
for (int i = 0; i < s.length(); i++) {
boolean[] vis = new boolean[s.length()];
vis[i] = true;
String temp = s.substring(i, i + 1);
arrangeS(s, vis, temp);
}
return set.toArray(new String[0]);
}
//递归处理
public void arrangeS(String s, boolean[] vis, String init) {
if (init.length() == s.length()){
set.add(init);
return;
}
for (int i = 0; i < s.length(); i++) {
String temp = init;
if (!vis[i]) {
temp += s.substring(i, i + 1);
vis[i] = true;
arrangeS(s,vis,temp);
vis[i] = false;
}
}
}
}
时间复杂度O(n!)
思路二:优化思路一(map存储)
- 因为题目中包含相同元素,所以部分分支可以不进行重复递归计算
- 可以用map记录遍历过的元素
class Solution {
Set<String> set = new HashSet<>();
public String[] permutation(String s) {
Map<String, Integer> map = new HashMap<>();
for (char c : s.toCharArray()
) {
map.put(String.valueOf(c), map.getOrDefault(String.valueOf(c), 0) + 1);
}
arrangeS(s,map,"");
return set.toArray(new String[0]);
}
public void arrangeS(String s, Map<String, Integer> map, String init) {
if (init.length() == s.length()) {
set.add(init);
return;
}
for (String temp : map.keySet()
) {
String str=init;
if (map.get(temp) != 0) {
map.put(temp, map.get(temp) - 1);
arrangeS(s, map, str + temp);
map.put(temp, map.get(temp) + 1);
}
}
}
}
时间复杂度O(n!)