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. 回溯到上一层,尝试其他选择
相关推荐
田梓燊6 分钟前
leetcode 234
算法·leetcode·职场和发展
Aaron15888 分钟前
RFSOC+VU13P中在线部分可重构技术的应用分析
人工智能·算法·matlab·fpga开发·重构·信息与通信·信号处理
yashuk14 分钟前
C语言入门教程:程序结构与算法举例
c语言·算法·教程·程序设计·开发过程
橙露18 分钟前
后端开发面试:高频项目经验描述模板(可直接背)
面试·职场和发展
zsc_11818 分钟前
pvz3解码小游戏求解算法 (二)
算法
hanbr26 分钟前
每日一题day1(Leetcode 76最小覆盖子串)
算法·leetcode
AI科技星27 分钟前
张祥前统一场论中两个电荷定义的统一性解析
开发语言·线性代数·算法·数学建模·平面
代码地平线28 分钟前
C语言实现堆与堆排序详解:从零手写到TopK算法及时间复杂度证明
c语言·开发语言·算法
小江的记录本28 分钟前
【大语言模型】大语言模型——核心概念(预训练、SFT监督微调、RLHF/RLAIF对齐、Token、Embedding、上下文窗口)
java·人工智能·后端·python·算法·语言模型·自然语言处理
炘爚30 分钟前
LeetCode(两两交换链表中的节点)
算法·leetcode·链表