leetcode46--全排列

题目

给定一个不含重复数字的数组 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 中的所有整数 互不相同

解析

这道题目是一道回溯算法问题,需要枚举出所有可能的情况。

回溯法:一种通过探索所有可能的候选解来找出所有的解的算法。如果候选解被确认不是一个解(或者至少不是最后一个解),回溯算法会通过在上一步进行一些变化抛弃该解,即回溯并且再次尝试。

深度优先搜索 算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。这个算法会 尽可能深 的搜索树的分支。当结点 v 的所在边都己被探寻过,搜索将 回溯 到发现结点 v 的那条边的起始结点。这一过程一直进行到已发现从源结点可达的所有结点为止。如果还存在未被发现的结点,则选择其中一个作为源结点并重复以上过程,整个进程反复进行直到所有结点都被访问为止。

基本逻辑

题目让我们返回一个List,我们需要定义res数组来作为返回的结果,另外需要定义一个List数组 path 作为res中的元素。我们利用Path来保证数组不重复。

在traverse,我们进行代码逻辑的书写。首先我们先遍历数组,

java 复制代码
    for(int i = 0;i < nums.length;i++){
            if(path.contains(nums[i])){
                continue;
            }else{
                path.add(nums[i]);
                traverse(nums);
                path.remove(path.size()-1);
            }
        }

这里的逻辑是,如果当前的数字已经在Path中之后,那么我们就跳过这个数字。如果不在的话,那么我们在以这个数字为根节点去递归。注意,如果数字不在这个Path中,我们进入else条件之中,要写上 path.add(nums[i]); 并且当我们递归结束,返回到这一层递归时,要把当前数字移除path中,来进行所有数字的枚举。

变量 path 所指向的列表 在深度优先遍历的过程中只有一份 ,深度优先遍历完成以后,回到了根结点,成为空列表。

问题

出现六个空列表

在 Java 中,参数传递是 值传递,对象类型变量在传参的过程中,复制的是变量的地址。这些地址被添加到 res 变量,但实际上指向的是同一块内存地址,因此我们会看到 666 个空的列表对象。解决的方法很简单,在 res.add(path); 这里做一次拷贝即可。

修改的部分:

java 复制代码
        if(path.size() == nums.length){
            res.add(new ArrayList<>(path));
            return;
        }

此时再提交到「力扣」上就能得到通过了。

代码

java 复制代码
class Solution {
    //使path和res每次不跟着刷新
    List<Integer> path = new ArrayList<>();
    List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> permute(int[] nums) {
        traverse(nums);
        return res;
    }
    void traverse(int[] nums){
        if(path.size() == nums.length){
            res.add(new ArrayList<>(path));
            return;
        }
        for(int i = 0;i < nums.length;i++){
            if(path.contains(nums[i])){
                continue;
            }else{
                path.add(nums[i]);
                traverse(nums);
                path.remove(path.size()-1);
            }
        }
    }
}
相关推荐
Neil今天也要学习10 小时前
永磁同步电机无速度算法--基于三阶LESO的反电动势观测器
算法·1024程序员节
机器学习之心10 小时前
NGO-VMD北方苍鹰算法优化变分模态分解+皮尔逊系数+小波阈值降噪+信号重构,MATLAB代码
算法·matlab·重构·信号重构·ngo-vmd·皮尔逊系数·小波阈值降噪
橘颂TA10 小时前
【剑斩OFFER】算法的暴力美学——山脉数组的蜂顶索引
算法·leetcode·职场和发展·c/c++
速易达网络10 小时前
C语言常见推理题
java·c语言·算法
freedom_1024_11 小时前
LRU缓存淘汰算法详解与C++实现
c++·算法·缓存
博语小屋11 小时前
力扣11.盛水最多的容器(medium)
算法·leetcode·职场和发展
Swift社区11 小时前
LeetCode 423 - 从英文中重建数字
算法·leetcode·职场和发展
点云SLAM11 小时前
算法与数据结构之二叉树(Binary Tree)
数据结构·算法·二叉树·深度优先·广度优先·宽度优先
小龙报12 小时前
《算法通关指南:算法基础篇 --- 一维前缀和 — 1. 【模板】一维前缀和,2.最大子段和》
c语言·数据结构·c++·算法·职场和发展·创业创新·visual studio
树在风中摇曳12 小时前
LeetCode 1658 | 将 x 减到 0 的最小操作数(C语言滑动窗口解法)
c语言·算法·leetcode