难度:中等
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面 不能有重复元素。
输入:s = “abc”
输出:[“abc”,“acb”,“bac”,“bca”,“cab”,“cba”]
限制:
1 <= s 的长度 <= 8
可以直接暴力穷举,但是如果字符串 s
内有重复字符,要考虑怎么去重。
hasUsed
数组来保存每一位是否被访问过;i > 0 && s[i - 1] == s[i] && !hasUsed[i - 1]
时,则 continue
跳过,即可去重。C++
class Solution {
private:
vector<string> ans;
void backtracking(const string& s, string& temp, vector<int>& hasUsed){
if(temp.size() == s.size()){
ans.push_back(temp);
return;
}
for(int i = 0; i < s.size(); i++){
if(hasUsed[i] == 1) continue;
//去重
if(i > 0 && s[i] == s[i - 1] && hasUsed[i - 1] == 0) continue;
hasUsed[i] = 1;
temp.push_back(s[i]);
backtracking(s, temp, hasUsed);
temp.pop_back();
hasUsed[i] = 0;
}
}
public:
vector<string> permutation(string s) {
sort(s.begin(), s.end());
string temp;
vector<int> hasUsed(s.size(), 0);
backtracking(s, temp, hasUsed);
return ans;
}
};
Java
class Solution {
private ArrayList<String> ret = new ArrayList<>();
private void backtracking(char[] cs, StringBuffer temp, int[] hasUsed){
if(temp.length() == cs.length){
ret.add(temp.toString());
return;
}
for(int i = 0; i < cs.length; i++){
if(hasUsed[i] == 1) continue;
//去重
if(i > 0 && cs[i] == cs[i - 1] && hasUsed[i - 1] == 0) continue;
hasUsed[i] = 1;
temp.append(cs[i]);
backtracking(cs, temp, hasUsed);
temp.deleteCharAt(temp.length() - 1);
hasUsed[i] = 0;
}
}
public String[] permutation(String s) {
char[] cs = s.toCharArray();
Arrays.sort(cs);
StringBuffer temp = new StringBuffer();
int[] hasUsed = new int[cs.length];
backtracking(cs, temp, hasUsed);
//转换为 String[] 型
int n = ret.size();
String[] ans = new String[n];
for(int i = 0; i < n; i++){
ans[i] = ret.get(i);
}
return ans;
}
}
n
为给定字符串的长度。这些字符的全部排列有 O ( n ! ) O(n!) O(n!) 个,每个排列平均需要 O ( n ) O(n) O(n)的时间来生成。题目来源:力扣。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!