九点半了,做题吧。聊天聊到十一点多哈哈。
1、题目描述
2、逻辑分析
给定一个不重复数组,要求返回所有可能的全排列。这道题跟我上一道题思想一致,都是使用到回溯的算法思想来解决。直接用代码来解释吧
3、代码演示
public List<List<Integer>> permute(int[] nums) {// 创建一个结果列表,用于存储所有排列 List<List<Integer>> res = new ArrayList<List<Integer>>();// 创建一个输出列表,用于在回溯过程中构建当前排列List<Integer> output = new ArrayList<>();// 初始化 output 列表,将 nums 数组中的所有元素添加到 output 中for(int num : nums){output.add(num);}// 获取 nums 数组的长度int n = nums.length;// 调用回溯方法,从索引 0 开始构建排列backtrack(n, output, res, 0);// 返回结果列表return res;}// 这是一个私有方法,用于回溯过程public void backtrack(int n, List<Integer> output, List<List<Integer>>res, int index){// 如果当前索引等于数组长度(即所有元素都已经被考虑过),则将当前 output 列表添加到结果列表中if(index == n){// 注意这里使用了 new ArrayList<>(output) 来创建一个新的列表实例, // 而不是直接将 output 添加到 res 中,这是为了防止后续对 output 的修改影响 res 中的结果 res.add(new ArrayList<Integer>(output));}// 从当前索引开始,遍历剩余的元素 for(int i = index; i < n; i++){// 交换当前索引和 i 索引的元素,这样可以生成新的排列 Collections.swap(output, index, i);// 递归调用 backtrack 方法,将索引加 1,以考虑下一个位置backtrack(n, output, res, index + 1);// 回溯,将之前交换的元素换回来,以便尝试其他排列Collections.swap(output, index, i);} }
其中值得注意的是:res.add(new ArrayList(output)) ;这里new了一个 output,不是直接将 output 添加到 res 中,这是为了防止后续对 output 的修改影响 res 中的结果。还有Collections.swap(output, index, i);将交换的元素再回溯回来,继续判断。
时间复杂度为 O ( n × n ! ) O(n\times n!) O(n×n!),空间复杂度为:O(n)。
不早了,这题略显敷衍一些,还没理解透,回去睡觉啦!拜拜晚安!