字符串的排列(回溯)
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
输入:s = "abc" 输出:["abc","acb","bac","bca","cab","cba"]
题解
-
回溯
- 算法思想(第一位所有可能的情况*在第一位确定的情况下第二位所有可能的情况……)
- 将字符串分为两个部分,再一次递归!
- 将字符串递归地分为前面一个元素和后面的元素
- 然后可以将前面的一个元素和后面的元素交换位置
- 以此递归
- 注意:需要注意重复的情况
- 复杂度分析
- 时间复杂度O(n!)
- 空间复杂度 O(n^2):栈的使用空间大小为 O(n);递归辅助 set 累计存储的字符数来能最多为 N+N-1+N-2+……+ 1 = (N+1)N/2,即 O(n^2)的额外空间
class Solution { ArrayList<String> list = new ArrayList<>(); char[] c; public String[] permutation(String s) { if(s.equals(""))return new String[0]; c = s.toCharArray(); dfs(0); return list.toArray(new String[c.length]); } void dfs(int index){ if(index == c.length-1){ list.add(String.valueOf(c)); return; } HashSet<Character> set = new HashSet<>(); for(int i = index;i < c.length; i++){ if(set.contains(c[i]))continue; set.add(c[i]); swap(index,i); dfs(index+1); swap(index,i); } } void swap(int a,int b){ char temp = c[a]; c[a] = c[b]; c[b] = temp; } }
- 算法思想(第一位所有可能的情况*在第一位确定的情况下第二位所有可能的情况……)
总结
- 操作字符串的时候可以考虑把字符串转换为字符数组
- 在不确定数组大小的时候,可以先创建 ArrayList,然后最后再转化为数组
- 在解决排列问题的时候可以考虑递归。