描述
输入一个字符串,打印出该字符串的所有排列。例如,输入字符串”abc”,则输出有字符’a’,’b’,’c’所能排列出来的所有字符串”abc”,”acb”,”bac”,”bca”,”cab”,”cba”。
解决方案
递归实现
从字符串中选出一个字符作为排列的第一个字符,然后对剩余的字符进行全排列。如此递归处理,从而得到所有字符的全排列。
/* * 参数arrayA:给定字符串的字符数组 参数start:开始遍历字符与其后面各个字符将要进行交换的位置 参数end:字符串数组的最后一位 * 函数功能:输出字符串数字的各个字符全排列 */ public void recursionArrange(char[] arrayA, int start, int end) { if (end < 1) return; if (start == end) { System.out.println(String.valueOf(arrayA)); } else { for (int i = start; i <= end; i++) { swap(arrayA, i, start); recursionArrange(arrayA, start + 1, end); swap(arrayA, i, start); } } } // 交换数组m位置和n位置上的值 public void swap(char[] arrayA, int m, int n) { if (m == n) { return; } char temp = arrayA[m]; arrayA[m] = arrayA[n]; arrayA[n] = temp; } public static void main(String[] args) { StringTest test = new StringTest(); String A = "abc"; char[] arrayA = A.toCharArray(); test.recursionArrange(arrayA, 0, arrayA.length - 1); }
代码优化点
其实end没有用到,可以去掉end,用 arrayA.length替代,省去了end作为入参。
回溯模板在此题的应用
性能不是很好,因为有contains()方法的存在,O(N)的复杂度。 但不失为一种模板思路。
List<List<Integer>> res = new LinkedList<>(); /* 主函数,输入一组不重复的数字,返回它们的全排列 */ List<List<Integer>> permute(int[] nums) { // 记录「路径」 LinkedList<Integer> track = new LinkedList<>(); backtrack(nums, track); return res; } // 路径:记录在 track 中 // 选择列表:nums 中不存在于 track 的那些元素 // 结束条件:nums 中的元素全都在 track 中出现 void backtrack(int[] nums, LinkedList<Integer> track) { // 触发结束条件 if (track.size() == nums.length) { res.add(new LinkedList(track)); return; } for (int i = 0; i < nums.length; i++) { // 排除不合法的选择 if (track.contains(nums[i])) continue; // 做选择 track.add(nums[i]); // 进入下一层决策树 backtrack(nums, track); // 取消选择 track.removeLast(); } }
public static void ss(String str) { ssH1(str.toCharArray(), new ArrayList<>()); } public static void ssH1(char[] chars, List<Character> tempList) { if (chars.length == tempList.size()) { String res = ""; for (Character character : tempList) { res += character; } strList.add(res); return; } for (int i = 0; i < chars.length; i++) { if (tempList.contains(chars[i])) { continue; } tempList.add(chars[i]); ssH1(chars, tempList); tempList.remove(tempList.size() - 1); } }