给出一组数字,返回该组数字的所有排列
例如:
[1,2,3]的所有排列如下
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2], [3,2,1].
(以数字在数组中的位置靠前为优先级,按字典序排列输出。)
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2], [3,2,1].
(以数字在数组中的位置靠前为优先级,按字典序排列输出。)
数据范围:数字个数
要求:空间复杂度 ,时间复杂度
[1,2,3]
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
[1]
[[1]]
ArrayList<ArrayList<Integer>> res=new ArrayList<ArrayList<Integer>>(); public ArrayList<ArrayList<Integer>> permute (int[] num) { // write code here Arrays.sort(num); recur(num ,new boolean[num.length] ,new ArrayList<>()); return res; } public void recur(int[] num ,boolean[] flag ,ArrayList<Integer> list){ if(list.size()==num.length){ res.add(new ArrayList<>(list)); return; } for(int i=0;i<num.length;i++){ if((i>0 && num[i]==num[i-1] && !flag[i]) || flag[i]){ continue; } list.add(num[i]); flag[i]=true; recur(num ,flag ,list); flag[i]=false; list.remove(list.size()-1); } }
if(num.length == list.size()){ res.add(new ArrayList<>(list)); return; }递归回溯套路
public class Solution { public ArrayList<ArrayList<Integer>> permute (int[] num) { // write code here ArrayList<ArrayList<Integer>> res = new ArrayList<>(); LinkedList<Integer> list = new LinkedList<>(); boolean[] visit = new boolean[num.length]; dfs(num,res,list,visit); return res; } private void dfs(int[] num, ArrayList<ArrayList<Integer>> res, LinkedList<Integer> list, boolean[] visit) { if(num.length == list.size()){ res.add(new ArrayList<>(list)); return; } for(int i=0;i<num.length;i++){ if(visit[i]){ continue; } visit[i] = true; list.add(num[i]); dfs(num,res,list,visit); list.pollLast(); visit[i] = false; } } }
public ArrayList<ArrayList<Integer>> permute (int[] num) { ArrayList<ArrayList<Integer>> ans=new ArrayList<>(); ArrayList<Integer> list=new ArrayList<>(); build(num,ans,list); return ans; } public void build(int[] num,ArrayList<ArrayList<Integer>> ans,ArrayList<Integer> list){ if(list.size()==num.length){ //截至条件(终止条件) ans.add(new ArrayList<>(list)); } for(int i=0;i<num.length;i++){ if(list.contains(num[i])){ //因为这个题没有重复的数字, 所以当list中已经有了这个数字,那就剪枝 continue; } list.add(num[i]); build(num,ans,list); list.remove(list.size()-1); } }
import java.util.*; import java.util.stream.Collectors; public class Solution { private ArrayList<ArrayList<Integer>> all = new ArrayList<ArrayList<Integer>>(); private ArrayList<Integer> current = new ArrayList<Integer>(); public ArrayList<ArrayList<Integer>> permute(int[] num) { int max = getMax(num); int[] numCount = new int[max + 1]; for (int idx = 0; idx < num.length; idx++) { numCount[num[idx]]++; } dfs(num, numCount, num.length); Set<ArrayList<Integer>> set = new HashSet<ArrayList<Integer>>(this.all); this.all.clear(); this.all.addAll(set); Collections.sort(this.all, new Comparator<ArrayList<Integer>>() { public int compare(ArrayList<Integer> self, ArrayList<Integer> other) { int min = Math.min(self.size(), other.size()); for (int idx = 0; idx < min; idx++) { if (self.get(idx) != other.get(idx)) { return self.get(idx).compareTo(other.get(idx)); } } if (self.size() > other.size()) { return self.get(min + 1); } else if (self.size() < other.size()) { return other.get(min + 1); } return 0; } }); return this.all; } public void dfs(int[] num, int[] numCount, int n) { if (this.current.size() == n) { this.all.add((ArrayList<Integer>)this.current.clone()); return; } for (int idx = 0; idx < n; idx++) { int count = getCount(this.current, num[idx]); if (count < numCount[num[idx]]) { this.current.add(num[idx]); dfs(num, numCount, n); this.current.remove(this.current.size() - 1); } } } public static int getCount(ArrayList<Integer> list, int num) { long count = list.stream().filter(item->item == num).collect( Collectors.counting()); return Long.valueOf(count).intValue(); } public static int getMax(int[] num) { int max = Integer.MIN_VALUE; for (int idx = 0; idx < num.length; idx++) { if (max < num[idx]) { max = num[idx]; } } return max; } }
import java.util.*; ## 经典回溯 public class Solution { List<Integer> list = new ArrayList<>(); ArrayList<ArrayList<Integer>> result = new ArrayList<>(); public ArrayList<ArrayList<Integer>> permute(int[] num) { Arrays.sort(num); dfs(num,list); return result; } private void dfs(int[] num,List<Integer> list){ if(list.size() == num.length){ result.add(new ArrayList<>(list)); return; } for(int i = 0; i < num.length; i ++){ if(list.contains(num[i])){ continue; } list.add(num[i]); dfs(num,list); list.remove(list.size() - 1); } } }
public ArrayList<ArrayList<Integer>> permute (int[] num) { ArrayList<ArrayList<Integer>> lists = new ArrayList<>(); test(lists,new ArrayList<>(),num); return lists; } public static void test(ArrayList<ArrayList<Integer>> lists, ArrayList<Integer> list, int[] nums) { if (list.size() == nums.length) { lists.add(new ArrayList<>(list)); return; } for (int i=0;i<nums.length;i++) { if (list.contains(nums[i])) continue; list.add(nums[i]); test(lists,list,nums); list.remove(list.size()-1); } }
import java.util.*; public class Solution { ArrayList<ArrayList<Integer>> res = new ArrayList<>(); public ArrayList<ArrayList<Integer>> permute(int[] num) { ArrayList<Integer> list = new ArrayList<>(); backTrack(num, list); return res; } public void backTrack(int[] num, ArrayList<Integer> list) { if (list.size() == num.length) { res.add(new ArrayList<>(list)); return; } for (int i = 0; i < num.length; i++) { if (list.contains(num[i])) continue; list.add(num[i]); backTrack(num, list); list.remove(list.size() - 1); } } }
import java.util.*; public class Solution { ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>(); public ArrayList<ArrayList<Integer>> permute(int[] num) { boolean[] isUsed = new boolean[num.length]; ArrayList<Integer> list = new ArrayList<>(); Arrays.sort(num); dfs(num, isUsed, list); return res; } public void dfs(int[] num, boolean[] isUsed, ArrayList<Integer> list) { if (list.size() == num.length) { res.add(new ArrayList(list)); } for (int i = 0; i < num.length; i ++) { if (isUsed[i] == true) continue; if (i > 1 && num[i] == num[i - 1]) continue; list.add(num[i]); isUsed[i] = true; dfs(num, isUsed, list); isUsed[i] = false; list.remove(list.size() - 1); } } }
import java.util.*; public class Solution { public ArrayList<ArrayList<Integer>> permute(int[] num) { ArrayList<ArrayList<Integer>> list=new ArrayList<ArrayList<Integer>>(); ArrayList<Integer> path=new ArrayList<Integer>(); dfs(num,path,list); return list; } public void dfs(int[] nums,ArrayList<Integer> path,ArrayList<ArrayList<Integer>> list){ if(path.size()==nums.length){ list.add(new ArrayList<Integer>(path)); return; } for(int i=0;i<=nums.length-1;i++){ if(path.contains(nums[i])){continue;} path.add(nums[i]); dfs(nums,path,list); path.remove(path.size()-1); } } }
import java.util.*; public class Solution { ArrayList<ArrayList<Integer>> res = new ArrayList<>(); ArrayList<Integer> track = new ArrayList<>(); public ArrayList<ArrayList<Integer>> permute(int[] num) { backtrack(num); return res; } public void backtrack(int[] num){ if(track.size()==num.length) { res.add(new ArrayList<Integer>(track)); return; } for(int i : num){ if(track.contains(i)) continue; track.add(i); backtrack(num); track.remove(track.size()-1); } return; } }
public class Solution { ArrayList<ArrayList<Integer>> ans = new ArrayList<ArrayList<Integer>>(); int len; public ArrayList<ArrayList<Integer>> permute(int[] num) { if(num==null||num.length==0) return ans; //先对数组排序保证最后返回的结果是按字典排序输出 Arrays.sort(num); len = num.length; //创建一个数组记录已经加入数组的元素 boolean[] isVisi = new boolean[len]; //递归添加元素 dfs(num,isVisi,new ArrayList()); return ans; } void dfs(int[] num,boolean[] vis,ArrayList<Integer> ls){ if(ls.size()==len){ ans.add(new ArrayList(ls)); return; } for(int i = 0;i<len;i++){ if(vis[i]) continue; vis[i] = true; ls.add(num[i]); dfs(num,vis,ls); //回溯 vis[i] = false; ls.remove(ls.size()-1); } } }
import java.util.*; public class Solution { public ArrayList<ArrayList<Integer>> permute(int[] num) { Arrays.sort(num); ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>(); if(num.length == 0){ return res; } ArrayList<Integer> list = new ArrayList<>(); //数组转list集合(重点!!!) for(int n : num){ list.add(n); } recursion(res, list, 0); return res; } int temp = 0; public void swap(ArrayList<Integer> list, int i1, int i2){ temp = list.get(i1); list.set(i1, list.get(i2)); list.set(i2, temp); } public void recursion(ArrayList<ArrayList<Integer>> res, ArrayList<Integer> list, int index){ if(index == list.size() - 1){ res.add(new ArrayList<>(list));//官方答案这里写错了,不new的话,存的内存地址就是同一个,那么就会相同结果 }else{ for(int i = index; i < list.size(); i++){ swap(list, i, index);//递归 recursion(res, list, index + 1); swap(list, i, index);//回溯 } } } }
import java.util.*; public class Solution { public void swap(ArrayList<Integer> nums, int i, int j) { if (i == j) { return; } int temp = nums.get(i); nums.set(i, nums.get(j)); nums.set(j, temp); } public void recursive(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> nums, int startIndex) { if (startIndex == nums.size() - 1) { result.add(new ArrayList<>(nums)); return; } for (int i = startIndex; i < nums.size(); i++) { swap(nums, startIndex, i); recursive(result, nums, startIndex + 1); swap(nums, startIndex, i); } } public ArrayList<ArrayList<Integer>> permute(int[] num) { ArrayList<Integer> nums = new ArrayList<>(); for (int n : num) { nums.add(n); } ArrayList<ArrayList<Integer>> result = new ArrayList<>(); recursive(result, nums, 0); return result; } }
import java.util.*; public class Solution { public ArrayList<ArrayList<Integer>> permute(int[] num) { int len = num.length; Deque path = new ArrayDeque(); ArrayList<ArrayList<Integer>> res = new ArrayList<>(); boolean[] used = new boolean[len]; if (len == 0){ return res; } dfs(path,used,num,res,0,len); return res; } public static void dfs(Deque<Integer> path, boolean[] used, int[] nums, ArrayList<ArrayList<Integer>> res,int depth,int len){ if (depth == len){ //终止递归 res.add(new ArrayList<>(path)); return; } for (int i = 0; i < len; i++) { if (!used[i]){ path.addLast(nums[i]); used[i] = true; dfs(path,used,nums,res,depth + 1,len); used[i] = false; path.removeLast(); } } } }
public class Solution { ArrayList<ArrayList<Integer>> res = new ArrayList<>(); ArrayList<Integer> list = new ArrayList<>(); public ArrayList<ArrayList<Integer>> permute(int[] num) { help(num); return res; } public void help(int[] num){ if(list.size() == num.length){ res.add(new ArrayList(list)); return; } for(int i = 0; i < num.length;i++){ if(list.contains(num[i])) continue; list.add(num[i]); help(num); list.remove(list.size()-1); } } }
简单粗暴:DFS + 回溯
import java.util.*; public class Solution { // 返回结果 private static ArrayList<ArrayList<Integer>> result = new ArrayList<>(); public ArrayList<ArrayList<Integer>> permute(int[] num) { boolean[] flags = new boolean[num.length]; dfs(num, flags, new LinkedList<>()); return result; } private void dfs(int[] num, boolean[] flags, LinkedList<Integer> temp) { // 结束标志 if (temp.size() == num.length) { result.add(new ArrayList<>(temp)); return; } for (int i = 0; i < num.length; i++) { if (flags[i]) { continue; } // 前进 flags[i] = true; temp.add(num[i]); dfs(num, flags, temp); // 回退 flags[i] = false; temp.removeLast(); } } }
import java.util.*; public class Solution { ArrayList<ArrayList<Integer>> res = new ArrayList<>(); // 记录访问过的数字 boolean[] vis; public ArrayList<ArrayList<Integer>> permute(int[] num) { ArrayList<Integer> tempRes = new ArrayList<>(); vis = new boolean[num.length]; for(int i = 0;i<vis.length;i++) vis[i] = false; backTrace(num,tempRes); return res; } public void backTrace(int[] num,ArrayList<Integer> temp){ if(temp.size() == num.length){ res.add(new ArrayList(temp)); return; } for(int i = 0;i<num.length;i++){ if(vis[i]) continue; temp.add(num[i]); vis[i] = true; backTrace(num,temp); // 回退 temp.remove(temp.size()-1); vis[i] = false; } } }