九点半了,做题吧。聊天聊到十一点多哈哈。
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)。
不早了,这题略显敷衍一些,还没理解透,回去睡觉啦!拜拜晚安!