zoukankan      html  css  js  c++  java
  • Medium | LeetCode 46. 全排列 | 回溯

    46. 全排列

    给定一个 没有重复 数字的序列,返回其所有可能的全排列。

    示例:

    输入: [1,2,3]
    输出:
    [
      [1,2,3],
      [1,3,2],
      [2,1,3],
      [2,3,1],
      [3,1,2],
      [3,2,1]
    ]
    

    解题思路

    经典的回溯算法问题

    下面采用交换的方式实现全排列

    public List<List<Integer>> permute(int[] nums) {
            List<List<Integer>> res = new ArrayList<List<Integer>>();
    
            List<Integer> output = new ArrayList<Integer>();
            for (int num : nums) {
                output.add(num);
            }
    
            int n = nums.length;
            backtrack(n, output, res, 0);
            return res;
        }
    
        public void backtrack(int n, List<Integer> output, List<List<Integer>> res, int first) {
            // 所有数都填完了
            if (first == n) {
                res.add(new ArrayList<Integer>(output));
            }
            for (int i = first; i < n; i++) {
                // 动态维护数组
                Collections.swap(output, first, i);
                // 继续递归填下一个数
                backtrack(n, output, res, first + 1);
                // 撤销操作
                Collections.swap(output, first, i);
            }
        }
    

    下面使用设置访问数组的方式实现全排列

    class Solution {
        
        private List<Integer> res;
        private boolean[] visit;
        private List<List<Integer>> resList = new ArrayList<>();
    
        public List<List<Integer>> permute(int[] nums) {
            if (nums.length == 0) {
                return resList;
            }
            res = new ArrayList<>(nums.length);
            visit = new boolean[nums.length];
            Arrays.fill(visit, false);
            permute(nums, 0);
            return resList;
        }
    
        public void permute(int[] nums, int index) {
            if(index == nums.length) {
                resList.add(new ArrayList<>(res));
                return;
            }
            for (int i = 0; i < nums.length; i++) {
                // 找到没有放过的数字
                if (!visit[i]) {
                    // 把当前数字放进去
                    res.add(nums[i]);
    
                    visit[i] = true;
                    // 放下一个数字
                    permute(nums, index+1);
                    // 然后把刚刚放进去的数字拿出来, 放下一个数字
                    res.remove(index);
                    visit[i] = false;
                }
            }
        }
    }
    
  • 相关阅读:
    Linux磁盘文件的命名
    操作系统的基本介绍
    CMOS、BIOS
    CPU的频率、外频、倍频与超频
    学习Linux——计算机概论
    第三季-第14课-有名管道通讯编程
    第三季-第13课-无名管道通讯编程
    第三季-第12课-多进程程序设计
    第三季-第11课-进程控制理论
    第三季-第10课-时间编程
  • 原文地址:https://www.cnblogs.com/chenrj97/p/14443152.html
Copyright © 2011-2022 走看看