题目
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:
输入:s = "abc" 输出:["abc","acb","bac","bca","cab","cba"]
解法一 Python版 容易超时
这版其实是我自己经常用的Python版,不稳定,容易超时,但是很简洁
class Solution(object):
def permutation(self, s):
"""
:type s: str
:rtype: List[str]
"""
result = []
self.recur(s,"",result)
return result
def recur(self,s,cur,result):
if not s:
if cur not in result:
result.append(cur)
return
for i in range(len(s)):
self.recur(s[:i]+s[i+1:],cur+s[i],result)
解法二 Java版 回溯算法
这个解法其实就是用回溯
class Solution {
List<String> result = new ArrayList<String>();
char[] candidates;
public String[] permutation(String s) {
candidates = s.toCharArray();
dfs(0);
return result.toArray(new String[result.size()]);
}
public void dfs(int index){
// 当到最后一层只剩一个时,把candidates化成string给加入result
if(index == candidates.length-1){
result.add(String.valueOf(candidates));
}
// 记录一下出现过的char,防止重复使用
HashSet<Character> set = new HashSet<Character>();
for(int i = index; i < candidates.length;i++){
if(set.contains(candidates[i])) continue;
// 把每个index后面的数,都换到index的位置来形成新的组合
swap(index,i);
dfs(index+1);
// 向下回溯后再换回来
swap(index,i);
}
}
public void swap(int a,int b){
char temp = candidates[a];
candidates[a] = candidates[b];
candidates[b] = temp;
}
}
时间复杂度 O(n!)
n为字符串 s 的长度;时间复杂度和字符串排列的方案数成线性关系,方案数为 n * (n-1) * (n-2) … ×2×1 ,因此复杂度为 O(n!)
空间复杂度 O(n^2)
递归中辅助 Set 累计存储的字符数量最多为 n + (n-1) + ... + 2 + 1 =(n+1)n/2 ,即占用 O(n^2) 的额外空间 。