LeetCode热题100--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]

题解

java 复制代码
import java.util.ArrayList;
import java.util.List;


public class Solution {

    public List<List<Integer>> permute(int[] nums) {
        
        int len = nums.length;
        
        List<List<Integer>> res = new ArrayList<>();

        if (len == 0) {
            return res;
        }

        boolean[] used = new boolean[len];
        List<Integer> path = new ArrayList<>();

        dfs(nums, len, 0, path, used, res);
        return res;
    }

    private void dfs(int[] nums, int len, int depth,
                     List<Integer> path, boolean[] used,
                     List<List<Integer>> res) {
        if (depth == len) {
            
            res.add(path);
            return;
        }

        for (int i = 0; i < len; i++) {
            if (!used[i]) {
                
                List<Integer> newPath = new ArrayList<>(path);
                newPath.add(nums[i]);

                boolean[] newUsed = new boolean[len];
                System.arraycopy(used, 0, newUsed, 0, len);
                newUsed[i] = true;

                dfs(nums, len, depth + 1, newPath, newUsed, res);
               
            }
        }
    }
}

解析

出自:liweiwei1419:回溯算法入门级详解 + 练习(持续更新)

java 复制代码
public List<List<Integer>> permute(int[] nums) {
    int len = nums.length;                    // 获取输入数组长度
    List<List<Integer>> res = new ArrayList<>(); // 创建结果列表,存储所有排列
    
    if (len == 0) {                          // 如果数组为空
        return res;                          // 直接返回空结果
    }
    
    boolean[] used = new boolean[len];       // 标记数组,记录哪些数字已被使用
    List<Integer> path = new ArrayList<>();  // 当前路径,存储正在构建的排列
    
    dfs(nums, len, 0, path, used, res);      // 调用深度优先搜索方法
    return res;                              // 返回所有排列结果
}
java 复制代码
private void dfs(int[] nums, int len, int depth,
                 List<Integer> path, boolean[] used,
                 List<List<Integer>> res) {
    if (depth == len) {                      // 终止条件:当前深度等于数组长度
        res.add(path);                       // 将完整排列添加到结果中
        return;                              // 返回上一层
    }
    
    for (int i = 0; i < len; i++) {          // 遍历所有数字
        if (!used[i]) {                      // 如果当前数字未被使用
            // 创建新路径(重要:避免引用传递问题)
            List<Integer> newPath = new ArrayList<>(path);
            newPath.add(nums[i]);            // 将当前数字添加到新路径
            
            // 创建新的使用标记数组
            boolean[] newUsed = new boolean[len];
            System.arraycopy(used, 0, newUsed, 0, len); // 复制原数组
            newUsed[i] = true;               // 标记当前数字为已使用
            
            // 递归调用,深度+1,使用新的路径和标记数组
            dfs(nums, len, depth + 1, newPath, newUsed, res);
        }
    }
}

执行流程:

  1. 从第一个位置开始,尝试所有未使用的数字
  2. 选择数字后标记为已使用,添加到路径中
  3. 递归处理下一个位置
  4. 当路径长度等于原数组长度时,保存结果
  5. 回溯到上一层,尝试其他选择
相关推荐
毕竟是shy哥2 小时前
计算YOLO数据集中每个类的目标数
算法·yolo·机器学习
M78佐菲2 小时前
Linux学习笔记:TCP协议
linux·笔记·学习·tcp/ip·算法
圣保罗的大教堂2 小时前
leetcode 1406. 石子游戏 III 困难
leetcode
晊晌_h3 小时前
嵌入式从0到精通——数据结构总结[特殊字符]
数据结构·算法·排序算法
我找到地球的支点啦4 小时前
Matlab系列(009) 一CRC循环冗余校验详解
开发语言·数据结构·算法·matlab·信息与通信
罗西的思考4 小时前
【OpenClaw具身硬件】ZeroClaw 源码阅读笔记(3)--- RAG
人工智能·算法·机器学习
浪里镖客5 小时前
位姿转换矩阵写法-个人习惯(计算机理解其实是相反的)
线性代数·算法·矩阵
丰锋ff5 小时前
面试问题合集
面试·职场和发展
颜挺锐5 小时前
如何轻松通过性能测试之第四篇:性能测试项目怎么交付?一文讲透九步实施流程(附面试话术 + 实战清单)
面试·职场和发展
小白羊丨8 小时前
如何诊断 Prompt 模板导致的效果下降?
人工智能·算法·prompt