剑指 Offer 38. 字符串的排列
文章目录
题目描述:
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof
示例:
示例 1:
输入:s = “abc”
输出:[“abc”,“acb”,“bac”,“bca”,“cab”,“cba”]
方法
数学公式
对于一个长度为
n
n
n 的字符串(假设字符互不重复),其排列方案数共有:
n
×
(
n
−
1
)
×
(
n
−
2
)
…
×
2
×
1
n\times(n-1) \times(n-2) \ldots \times2 \times1
n×(n−1)×(n−2)…×2×1
Java
回溯法backtracking
class Solution {
private Set<String> set;
private int len;
private void swap(char[]cs,int i,int j){
char c=cs[i];
cs[i]=cs[j];
cs[j]=c;
}
private void backtrace(char[]cs,int start){
if(start==len-1){
String copy=new String(cs);
set.add(copy);
return;
}
for(int i=start;i<len;i++){
if(i!=start&&cs[i]==cs[start]){
continue;
}
swap(cs,i,start);
backtrace(cs,start+1);
swap(cs,i,start);
}
}
public String[] permutation(String s) {
set=new HashSet<>();
len=s.length();
char[]cs=s.toCharArray();
backtrace(cs,0);
int num=set.size();
String[] res=new String[num];
int i=0;
for(String str:set){
res[i++]=str;
}
return res;
}
}
C++
回溯法backtracking
class Solution {
public:
vector<string> rec;
vector<int> vis;
void backtrack(const string& s, int i, int n, string& perm) {
if (i == n) {
rec.push_back(perm);
return;
}
for (int j = 0; j < n; j++) {
if (vis[j] || (j > 0 && !vis[j - 1] && s[j - 1] == s[j])) {
continue;
}
vis[j] = true;
perm.push_back(s[j]);
backtrack(s, i + 1, n, perm);
perm.pop_back();
vis[j] = false;
}
}
vector<string> permutation(string s) {
int n = s.size();
vis.resize(n);
sort(s.begin(), s.end());
string perm;
backtrack(s, 0, n, perm);
return rec;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/solution/zi-fu-chuan-de-pai-lie-by-leetcode-solut-hhvs/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。