今日题目:全排列 (2021.11.1)

106 阅读1分钟

这是我参与11月更文挑战的第1天

1. 题目描述

官方链接:全排列1
给定一个不含重复数字的数组 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. 问题分析。

看到此类排列组合问题,第一反应肯定是递归回溯算法解决。

3. 解答

   class Solution {
    List<List<Integer>>   ans = new ArrayList() ;
     public List<List<Integer>> permute(int[] nums) {
     //1.新建栈和访问列表
        ArrayDeque<Integer> deque = new ArrayDeque<>() ;
        int n = nums.length ;
        boolean[] visited = new boolean[n] ;
        dfs(0 ,nums,visited,deque) ;        
        return ans ;
    }

    public void backTrack(int count , int[] nums, boolean[] visited , ArrayDeque<Integer> deque ){
    //2.使用元素数量和数组长度相等时,返回。
        if(count == nums.length){
            ans.add(new ArrayList(deque)) ;
            return ;
        }

        for(int i = 0 ; i < visited.length ;i++){
            if(visited[i])
                continue ;
            //3.添加元素,修改访问列表
            deque.offerLast(nums[i]) ;
            visited[i] = true ;
             //4.展开递归树
            dfs(count+1 ,nums,visited,deque) ;
            //5.撤销修改,完成回溯。
            visited[i] = false ;
            deque.pollLast() ;
        }
    }   
}

4. 回溯算法

公式化来讲可以分为三步:

  • 向栈里添加元素,修改访问列表
  • 进行递归
  • 撤销上一步修改

image.png