408算法练习——全排列

全排列

问题链接:https://leetcode-cn.com/problems/permutations/

一、问题描述

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 

示例 1:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例 2:

输入:nums = [0,1]
输出:[[0,1],[1,0]]
示例 3:

输入:nums = [1]
输出:[[1]]

 

二、问题分析

  这是一道典型的回溯法的问题,下面解释代码

三、代码

  

 1 class Solution {
 2      public List<List<Integer>> permute(int[] nums) {
 3         List<List<Integer>> res = new ArrayList<List<Integer>>();
 4 
 5         List<Integer> output = new ArrayList<Integer>();
 6         //定义一个标记数组用来记录当前元素是否已经加入到结果数组中
 7         int flag[] = new int[nums.length];
 8 
 9         int n = nums.length;
10         backtrack(n,flag,nums, output, res, 0);
11         return res;
12     }
13 
14     public void backtrack(int n, int[] flag,int[] nums,List<Integer> output, List<List<Integer>> res, int first) {
15         // 用first来记录当前要将元素添加到结果数组的位置
16         if (first == n) {
17             res.add(new ArrayList<Integer>(output));
18             return;
19         }else{
20             for (int i = 0; i < n; i++) {
21             if(flag[i] != 1){
22                 output.add(nums[i]);
23                 flag[i]=1;
24                  // 继续递归填下一个数
25                 backtrack(n,flag,nums, output, res, first + 1);
26                 // 撤销操作
27                 output.remove(output.size()-1);
28                 flag[i]=0;
29             }
30             
31             }
32         }
33     }
34 }

定义一个flag数组标记数组中元素是否被使用过,如果使用过就找下一个未被使用的元素,first用来记录当前要输出的结果遍历到的位置,就是说从0开始到最后,依次给每个位置填入一个nums中的数,然后因为flag数组的影响每次都会选择不同的数填入,这样就会产生多个分支。在递归完成后要恢复结果数组的初始状态,就是说这些数据怎么进的递归就要怎么出递归,这样才能用于下一次的循环操作

 

posted @ 2021-07-16 21:03  瑜琦  阅读(134)  评论(0)    收藏  举报