46. 全排列 + 全排列 + 递归

题目来源

LeetCode_46

题目描述

给定一个不含重复数字的数组 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 <= nums.length <= 6
  • -10 <= nums[i] <= 10
  • nums 中的所有整数 互不相同

相似题目

LeetCode-78. 子集
LeetCode-46. 全排列
LeetCode-47. 全排列 II

题解分析

解法一:回溯法

image

  1. 本题与【子集】问题很类似,只不过这里是求解全排列,它们都需要用到回溯方法。
  2. 与【子集】问题不同的是,在递归里面,子集是从pos的位置开始遍历,而【全排列】问题需要从0开始遍历。因此,在本题中,我们需要额外使用一个布尔数组来判断一个位置的元素是否已经被使用过,使用过的元素将不能再添加到结果队列中。
  3. 回溯的关键在于,在递归回来时,需要把boolean数组和结果栈都恢复为原样,这样才能得到不同的其他满足条件的结果。
class Solution {
    List<List<Integer>> res = new LinkedList<>();
    boolean[] isUsed;
    public List<List<Integer>> permute(int[] nums) {
        isUsed = new boolean[nums.length];
        dfs(nums, 0, new LinkedList<Integer>());
        return res;
    }

    private void dfs(int[] nums, int pos, LinkedList<Integer> sta){
        if(pos == nums.length){
            res.add(new LinkedList<Integer>(sta));
            return;
        }
        for(int i=0; i<nums.length; i++){
            if(isUsed[i]){
                continue;
            }
            isUsed[i] = true;
            sta.offerLast(nums[i]);
            dfs(nums, pos + 1, sta);
            isUsed[i] = false;
            sta.pollLast();
        }
    }
}

复杂度分析

posted @ 2021-03-07 21:24  Garrett_Wale  阅读(78)  评论(0编辑  收藏  举报