题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
解题思路
常规dfs,字典序就先sort,还要去重,一开始一直想在根源处去重,无果。然后想着把结果存到set里,能用find函数找到就不push_back,因为没传引用,导致记忆失败。接着没意识到错误,利用map进行标记,失败。后来终于意识到错误,加了引用AC。
Code
class Solution {
public:
vector<string> Permutation(string str) {
int len = str.length();
sort(str.begin(), str.end());
bool vis[len+1];
memset(vis, false, sizeof(vis));
string currentString = "";
vector<string> res;
map<string, int> uniqueRes;
if(str.length()) PermutationCore(vis, currentString, str, res, uniqueRes);
return res;
}
void PermutationCore(bool vis[], string currentString, string str, vector<string> &res, map<string, int> &uniqueRes) {
int len = str.length();
if(currentString.length() == len) {
if(uniqueRes[currentString] == 0) {
res.push_back(currentString);
uniqueRes[currentString] = 1;
}
return ;
}
for(int i = 0; i<len; i++) {
if(!vis[i]) {
vis[i] = 1;
PermutationCore(vis, currentString+str[i], str, res, uniqueRes);
vis[i] = 0;
}
}
}
};
- java
import java.util.ArrayList;
import java.util.TreeSet;
public class Solution {
private boolean[] vis = new boolean[11];
private TreeSet<String> result = new TreeSet<String>();
private StringBuilder sb = new StringBuilder();
public void dfs(String str) {
if(sb.length() == str.length()) {
result.add(sb.toString());
return ;
}
for(int i = 0; i<str.length(); i++) {
if(!vis[i]) {
vis[i] = true;
sb.append(str.charAt(i));
dfs(str);
sb.deleteCharAt(sb.length()-1);
vis[i] = false;
}
}
}
public ArrayList<String> Permutation(String str) {
if(str == null || str.length() == 0) return new ArrayList<String>();
dfs(str);
return new ArrayList<String>(result);
}
}
总结
- 没有传引用在回溯后就会失去之前存过的数据
- 字符串判空
- java
1 str == null;
2 “”.equals(str);
3 str.length <= 0;
4 str.isEmpty();
- cpp
str.empty() || !str.size() || !str.length() || str == ""
- 补充一点StringBuilder的知识
- 线程不安全
sb.length()
.append(ch)
.deleteCharAt(sb.length()-1)
.setLength(sb.length()-1)