import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; public class Permutation { //方法一:回溯 public List<List<Integer>> permute1(int[] nums) { //定义保存结果的list ArrayList<List<Integer>> result = new ArrayList<>(); //用一个ArrayList保存一组解 ArrayList<Integer> solution = new ArrayList<>(); //从0位置开始填充数 backtrack1(nums,result,solution,0); return result; } //定义一个辅助集合,保存已经用过的数 HashSet<Integer> filled = new HashSet<>(); //实现一个回溯方法 public void backtrack1(int[] nums,List<List<Integer>> result,List<Integer> solution,int i){ int n = nums.length; //首先,判断退出递归调用的场景 if(i>=n){ result.add(new ArrayList<>(solution)); }else { //需要对i位置进行选数填入,需要遍历数组中所有数,取没有用过的数进行填充 for (int j = 0; j <n ; j++) { if(!filled.contains(nums[j])){ //没用过直接填入 solution.add(nums[j]); filled.add(nums[j]); //递归调用,处理下一个位置 backtrack1(nums,result,solution,i+1); //回溯,回退状态 solution.remove(i); filled.remove(nums[j]); } } } } //方法二:空间优化 public List<List<Integer>> permute(int[] nums) { //定义保存结果的list ArrayList<List<Integer>> result = new ArrayList<>(); //用一个ArrayList保存一组解 ArrayList<Integer> solution = new ArrayList<>(); //把nums复制到solution for (int num : nums) { solution.add(num); } //从0位置开始填充数 backtrack(result,solution,0); return result; } public void backtrack(List<List<Integer>> result, List<Integer> solution, int i){ int n = solution.size(); // 首先判断退出递归调用的场景 if (i >= n){ result.add(new ArrayList<>(solution)); } else { // 需要对i位置选数填入,遍历数组中所有数,取没有用过的数进行填充 for (int j = i; j < n; j++){ Collections.swap(solution, i, j); // 递归调用,处理后面的位置 backtrack(result, solution, i + 1); // 回溯 Collections.swap(solution, i, j); } } } public static void main(String[] args) { int[] nums = {1,2,3}; Permutation permutation = new Permutation(); List<List<Integer>> result = permutation.permute(nums); for (List<Integer> solution : result) { for (Integer num : solution) { System.out.print(num+"\t"); } System.out.println(); } } }