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);
            }
        }
    }
}
相关推荐
A旧城以西7 分钟前
数据结构(JAVA)单向,双向链表
java·开发语言·数据结构·学习·链表·intellij-idea·idea
杉之24 分钟前
选择排序笔记
java·算法·排序算法
烂蜻蜓39 分钟前
C 语言中的递归:概念、应用与实例解析
c语言·数据结构·算法
OYangxf40 分钟前
图论----拓扑排序
算法·图论
我要昵称干什么1 小时前
基于S函数的simulink仿真
人工智能·算法
AndrewHZ1 小时前
【图像处理基石】什么是tone mapping?
图像处理·人工智能·算法·计算机视觉·hdr
念九_ysl1 小时前
基数排序算法解析与TypeScript实现
前端·算法·typescript·排序算法
守正出琦1 小时前
日期类的实现
数据结构·c++·算法
ChoSeitaku1 小时前
NO.63十六届蓝桥杯备战|基础算法-⼆分答案|木材加工|砍树|跳石头(C++)
c++·算法·蓝桥杯
YueiL2 小时前
C++入门练习之 给出年分m和一年中的第n天,算出第n天是几月几号
开发语言·c++·算法