输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组。
例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。
数据范围:
要求:空间复杂度 ,时间复杂度
要求:空间复杂度 ,时间复杂度
输入一个字符串,长度不超过10,字符只包括大小写字母。
"ab"
["ab","ba"]
返回["ba","ab"]也是正确的
"aab"
["aab","aba","baa"]
"abc"
["abc","acb","bac","bca","cab","cba"]
""
[""]
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param str string字符串 * @return string字符串ArrayList */ public ArrayList<String> Permutation (String str) { // write code here ArrayList<String> result = new ArrayList<String>(); if (str == null) { return result; } Set<String> set = new HashSet<String>(); char[] array = str.toCharArray(); helper(array, 0, set); //用hashset是为了去重,如果是arraylist的话会有重复 for(String s : set){ result.add(s); } return result; } private void helper(char[] array, int index, Set<String> set) { if (index == array.length) { set.add(new String(array)); return; } for (int i = index; i < array.length; i++) { swap(array, index, i); helper(array, index + 1,set); swap(array, index, i); } } private void swap(char[] array, int i, int j) { char k = array[i]; array[i] = array[j]; array[j] = k; } }
public ArrayList<String> Permutation (String str) { HashSet<String> set = new HashSet<>(); p(str.toCharArray(),0,set); return new ArrayList<String>(set); } public void p(char[] str,int start,HashSet<String> set){ if(start == str.length) set.add(new String(str)); for(int i=start;i<str.length;i++){ if(i>start && str[start] == str[i]) continue; swap(str,start,i); p(str,start+1,set); swap(str,start,i); } } public void swap(char[] str,int i,int j){ char c = str[i]; str[i] = str[j]; str[j] = c; }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param str string字符串 * @return string字符串ArrayList */ public ArrayList<String> Permutation (String str) { char[] chs = str.toCharArray(); backTrack(chs); return res; } ArrayList<String> res = new ArrayList<>(); StringBuilder path = new StringBuilder(); HashSet<Integer> used = new HashSet<>(); // 记录每个path(纵向)使用过的字符索引 private void backTrack(char[] chs) { if (path.length() == chs.length) { res.add(path.toString()); return; } HashSet<Character> usedRow = new HashSet<>(); // 记录每层使用过的字符 for (int i = 0; i < chs.length; i++) { if (used.contains(i) || usedRow.contains(chs[i])) continue; path.append(chs[i]); used.add(i); usedRow.add(chs[i]); backTrack(chs); path.delete(path.length() - 1, path.length()); used.remove(i); } } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param str string字符串 * @return string字符串ArrayList */ public ArrayList<String> Permutation (String str) { // write code here // 左程云老师讲过全排列的分支限界递归法解决不重复全排列问题 // 调用一个递归函数,这个递归函数负责对当前i位置的字符进行与i ~ chars.length - 1中的位置依次互换,然后继续考察i + 1处的情况 // 分支界限法去重:定义一个HashSet,这个位置没有出现过该值才允许进入分支,否则跳过 // 算法的时间复杂度0(N!),额外空间复杂度0(N!) // 用于记录所有路径的结果 ArrayList<String> finalResults = new ArrayList<>(); // 调用这个递归函数,从num数组的0位置开始,将每一次找到的oneResult填进finalResult中 process(str.toCharArray(), finalResults, 0); // 返回最终的答案finalResults return finalResults; } public void process(char[] chars, ArrayList<String> finalResults, int i) { // 递归出口(底部) if (i == chars.length) { // i越界了,说明整个数组遍历完毕了,将单个路径上的答案oneResult写入总答案finalResults中 finalResults.add(String.valueOf(chars)); } // 递归分支 HashSet<Character> set = new HashSet<>(); for (int j = i; j < chars.length; j++) { if (!set.contains(chars[j])) { // 将num[j]登记 set.add(chars[j]); // 假设本位置与j位置的元素交换 swap(chars, i, j); // 在交换完的基础上继续考察num数组中i+1往后的位置该如何排列 process(chars, finalResults, i + 1); // 注意!恢复现场,继续尝试将本位值与num[j + 1]位置的元素交换 // 踩坑点2:一定要【恢复现场】,要不然无法准确列出要分支的情况 swap(chars, j, i); } } } // 数组元素交换函数 public void swap(char[] chars, int i, int j) { if (i == j) { return; } char t = chars[i]; chars[i] = chars[j]; chars[j] = t; } }
HashSet<String> res=new HashSet<>(); public ArrayList<String> Permutation (String str) { // write code here dfs(str.toCharArray() ,new boolean[str.length()] ,new StringBuilder()); return new ArrayList<String>(res); } public void dfs(char[] cs ,boolean[] flag ,StringBuilder sb){ if(sb.length()==cs.length){ res.add(sb.toString()); return; } for(int i=0;i<cs.length;i++){ if(flag[i]){ continue; } flag[i]=true; sb.append(cs[i]); dfs(cs ,flag ,sb); sb.deleteCharAt(sb.length()-1); flag[i]=false; } }
/* 全排列版本 */ public class Solution { public ArrayList<String> Permutation (String str) { // write code here char[] charArray = str.toCharArray(); Arrays.sort(charArray); str = new String(charArray); ArrayList<String> res = new ArrayList<>(); String list = ""; boolean[] visit = new boolean[str.length()]; dfs(str,res,list,visit); return res; } private void dfs(String str,ArrayList<String> res,String list,boolean[] visit){ if(str.length() == list.length()){ res.add(list); return; } for(int i =0;i<str.length();i++){ if(visit[i] || i>0&&str.charAt(i)==str.charAt(i-1) && visit[i-1]){ continue; } visit[i] = true; list += str.charAt(i); dfs(str,res,list,visit); list = list.replaceAll(".$",""); visit[i] = false; } } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param str string字符串 * @return string字符串ArrayList */ public ArrayList<String> Permutation (String str) { // write code here if (str.length() < 2) { return new ArrayList<String>(Arrays.asList(str)); } ArrayList<String> possibles = new ArrayList<String>(); for (int i = 0; i < str.length(); i++) { String prefix = String.valueOf(str.charAt(i)); String leftPart = str.substring(0, i); // Skip duplicates if (leftPart.contains(prefix)) { continue; } ArrayList<String> results = Permutation( // String without current character leftPart + str.substring(i + 1, str.length()) ); results.forEach((result) -> { possibles.add(prefix + result); }); } return possibles; } }
public ArrayList<String> Permutation (String str) { // 全排列 //String变char[] char[] charrr=str.toCharArray();//String变char[]:str.toCharArray() //排序(去重必然排序 Arrays.sort(charrr); boolean[] used=new boolean[str.length()]; ArrayList<String> ans=new ArrayList<>(); ArrayList<Character> list=new ArrayList<>();//作为path build(charrr,used,ans,list); return ans; } public void build(char[] charrr,boolean[] used,ArrayList<String> ans,ArrayList<Character> list){ //截至条件:list.size()==char.length //把char拼接到String上 用StringBuilder if(list.size()==charrr.length){ StringBuilder sb=new StringBuilder(); for(int i=0;i<list.size();i++){ sb.append(list.get(i)); } ans.add(sb.toString()); //把StringBuilder变成String, sb.toString() return; } for(int i=0;i<charrr.length;i++){ //剪枝 //被用过是true if(used[i]==true) continue; if(i>0&&charrr[i]==charrr[i-1]&&used[i-1]==true) continue; list.add(charrr[i]); used[i]=true; build(charrr,used,ans,list); list.remove(list.size()-1); used[i]=false; } }
import java.util.ArrayList; import java.util.Collections; public class Solution { public ArrayList<String> Permutation(String str) { ArrayList<String> list = new ArrayList<String>(); if(str!=null&&str.length()>0) { helper(str.toCharArray(), 0, list); Collections.sort(list); } return list; } public void helper(char[] chars, int i, ArrayList<String> list) { int len = chars.length; if(i==len-1) { String s = String.valueOf(chars); if(!list.contains(s)){ list.add(s); } } else{ for(int j=i; j<len; j++) { swap(chars, i, j); helper(chars, i+1, list); swap(chars, i, j); } } } public void swap(char[] cs, int i, int j){ char temp = cs[i]; cs[i] = cs[j]; cs[j] = temp; } }
public class Solution { public ArrayList<String> Permutation(String str) { // 将字符串转为字符数组 char[] sArray = str.toCharArray(); // 排序,为了后面对树层去重 Arrays.sort(sArray); // 路径 LinkedList<Character> track = new LinkedList<>(); // 结果集 ArrayList<String> ans = new ArrayList<>(); // 辅助树枝去重和树层去重 boolean[] used = new boolean[sArray.length]; backTrack(sArray, track, ans, used); return ans; } private void backTrack(char[] sArray, LinkedList<Character> track, ArrayList<String> ans, boolean[] used) { //收获结果 if (sArray.length == track.size()) { ans.add(parseToString(track)); return; } for (int i = 0; i < sArray.length; i++) { // 同一个树枝上一个数不可以出现两次 if (used[i]) { continue; } // 同一层不能选择同一个数 if (i > 0 && sArray[i] == sArray[i - 1] && !used[i - 1]) { continue; } // 标记本次选择 used[i] = true; // 做出选择 track.addLast(sArray[i]); backTrack(sArray, track, ans, used); // 撤销标记本次选择 used[i] = false; // 撤销选择 track.removeLast(); } } private String parseToString(LinkedList<Character> track) { // 将track转变为字符串返回 StringBuilder ans = new StringBuilder(); for (Character c : track) { ans.append(c); } return ans.toString(); } }
import java.util.ArrayList; import java.util.stream.Collectors; import java.util.*; public class Solution { public ArrayList<String> Permutation(String str) { char[] chars = str.toCharArray(); ArrayList<String> list = new ArrayList<String>(); if (str == null || str == "") { list.add(""); return list; } per(chars, new Stack(), list, chars.length); return list; } public void per(char[] arr, Stack stack, List<String> list, int size) { if (arr.length <= 0) { Character[] character = new Character[size]; stack.copyInto(character); String str = Arrays.stream(character).map(String::valueOf).collect( Collectors.joining()); if (!list.contains(str)) { list.add(str); } } else { for (int i = 0; i < arr.length; i++) { char[] tempChars = new char[arr.length - 1]; System.arraycopy(arr, 0, tempChars, 0, i); System.arraycopy(arr, i + 1, tempChars, i, arr.length - 1 - i); stack.push(arr[i]); per(tempChars, stack, list, size); stack.pop(); } } } }
import java.util.*; public class Solution { public ArrayList<String> Permutation(String str) { if (Objects.isNull(str) || str.isEmpty()) return new ArrayList<>(); HashSet<String> set = new HashSet<>(); generatStr(str, 0, set); return new ArrayList(set); } private void generatStr(String str, int i, HashSet<String> set) { char[] chars = str.toCharArray(); // 第i位置的字符与str后面每个位置换一遍 for (int i1 = i; i1 < chars.length; i1++) { char temp = chars[i]; chars[i] = chars[i1]; chars[i1] = temp; set.add(String.valueOf(chars)); // 得到的新字符串,再接着与后面的交换(如题目画的图那样) generatStr(String.valueOf(chars), i + 1, set); } } }
import java.util.*; public class Solution { public ArrayList<String> Permutation(String str) { ArrayList<String> res = new ArrayList<>(); char[] chars = str.toCharArray(); Permutation(chars, res, 0); return res; } public void Permutation(char[] chars, ArrayList<String> res, int i) { if(i == chars.length){ res.add(new String(chars)); return; } // 每一层都使用一个hashset 来保存没有重复的字符,如果有重复,则不递归尝试获取排列 HashSet<Character> temp = new HashSet<>(); // 每个j位置的数都有机会来到i位置 for (int j = i; j < chars.length; j++) { // 只要set中不包含j索引的字符,那么递归求解 if(!temp.contains(chars[j])){ // 添加记录 temp.add(chars[j]); // 交换位置 permutationSwap(chars, i, j); // 递归求解 Permutation(chars, res, i+1); // 交换回来,下次循环继续 permutationSwap(chars, i, j); } } } public void permutationSwap(char[] chars, int i, int j){ char temp = chars[i]; chars[i] = chars[j]; chars[j] = temp; } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param str string字符串 * @return string字符串ArrayList */ public ArrayList<String> Permutation (String str) { ArrayList<String> result = new ArrayList<String>(); StringBuilder sb = new StringBuilder(); char[] charArr = str.toCharArray(); Arrays.sort(charArr); backTrack(result, sb, charArr, new boolean[charArr.length]); return result; } private void backTrack(ArrayList<String> result, StringBuilder sb, char[] charArr, boolean[] visited) { if (sb.length() == charArr.length) { result.add(sb.toString()); return; } for (int i = 0; i < charArr.length; i++) { if (visited[i]) continue; if (i > 0 && charArr[i - 1] == charArr[i] && visited[i - 1]) continue; visited[i] = true; sb.append(charArr[i]); backTrack(result, sb, charArr, visited); visited[i] = false; sb.deleteCharAt(sb.length() - 1); } } }