输入一个长度为 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"]
""
[""]
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); } } }
超时 import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param str string字符串 * @return string字符串ArrayList */ ArrayList<String> res = new ArrayList<String>(); public ArrayList<String> Permutation (String str) { // write code here char[] c = str.toCharArray(); Arrays.sort(c); // 记录访问过的字符 ArrayList<Character> path = new ArrayList<Character>(); // 记录字符是否访问过 boolean[] visited = new boolean[c.length]; dfs(c,path,visited); return res; } public void dfs(char[] c,ArrayList<Character> path,boolean[] visited){ // 结束条件 if(path.size() == c.length){ StringBuilder str = new StringBuilder(); for(char cc : path){ str.append(cc); } res.add(str.toString()); return; } for(int i=0; i<c.length; i++){ // 如果字符已经在path路径里面就跳过 if(visited[i]) continue; // 如果有重复字符且前面已经处理过就跳过,注意!visited[i-1]的!非常关键,只有在回溯过后才会进入处理处理 if(i > 0 && c[i] == c[i-1] && !visited[i-1]) continue; path.add(c[i]); visited[i] = true; dfs(c,path,visited); // 回溯 path.remove(path.size()-1); visited[i] = false; } } }