一、题目描述
1.1 题目
-
全排列
-
给定一个没有重复数字的序列,返回其所有可能的全排列。
-
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
1.2 知识点
- 回溯算法
1.3 题目链接
二、解题思路
2.1 自研思路
全排列题型,典型的回溯算法思想,这道题我的解题思路就是一层层深入,当递进到最后一层时进行回退,在回退后选择两个值进行交换,然后再次深入,当再次低级深入到最后一层时将排列添加到结果数组中。
举个例子,比如对于题中的 [1, 2, 3] 进行全排列,我们层层深入到最后一层 [1, 2, 3] ,然后将该值添加到结果列表中,然后回退一层至下标 1 处,然后交换 下标 1 和下标 2 处的值,递进后得到 [1, 3, 2] 并将其添加至结果数组中,然后再次回退两层至下标 0 处,交换下标 0 和下标 1 处的值得 [2, 1, 3],在递进到最后一层后将其添加到结果列表中,然后再回退一层至 下标 1 处,交换下标 1 和下标 2 处的值得 [2, 3, 1] 并将其添加到结果列表中,然后再次回退两层至下标 0 处,这次交换下标 0 和下标 2 处的值得到 [3, 2, 1] ,然后再向上述操作一样依次递进和回退,即可完成所有全排列的搜索。总结来说,这种思路的核心思想就是 交换 递进 … 回退 复原 ,且当递进至最后一层时将得到的结果添加至结果列表中。
三、实现代码
3.1 自研实现
class Solution {
private List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> permute(int[] nums) {
backtrack(0, nums);
return res;
}
public void backtrack(int index, int[] nums){
if(index == nums.length){
ArrayList<Integer> list = new ArrayList<>(nums.length);
for(int num : nums) list.add(num);
res.add(list);
return;
}
for(int i = 0; i < nums.length-index; i++){
// 交换
int temp = nums[index];
nums[index] = nums[index+i];
nums[index+i] = temp;
backtrack(index+1, nums);
// 复原
temp = nums[index];
nums[index] = nums[index+i];
nums[index+i] = temp;
}
}
}