全排列(LeetCode #43)
全排列(LeetCode #63)
题目:给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
题目链接:https://leetcode-cn.com/problems/permutations
解题思路
关于排列组合的题目,我们采用穷举法,先固定第一位为 1,然后第二位可以是 2,那么第三位只能是 3;然后可以把第二位变成 3,第三位就只能是 2 了;然后就只能变化第一位,变成 2,然后再穷举后两位……
算法原理
使用回溯算法,选择了一个节点后,递归选择剩下的节点,然后在回溯到上一个节点。
算法流程
- 判断递归结束条件:当所选路径到达最后一个节点时,即track.size() == nums.length
- 遍历所以可以选择的路径
- 跳过已经不合法的选择
- 将合法的节点加入到路径中
- 继续递归选择:backtrack(路径,选择列表)
- 撤销选择
、
我们从根节点开始遍历这颗树,所有路径上组合的数字就是我们想要的排列。
代码实现
class Solution {
List<List<Integer>> res = new LinkedList<>();
public List<List<Integer>> permute(int[] nums) {
LinkedList<Integer> track = new LinkedList<>();
baketrack(nums, track);
return res;
}
void baketrack(int[] nums, LinkedList<Integer> track) {
//end condition
if(nums.length == track.size()) {
res.add(new LinkedList(track));
return;
}
for(int i = 0;i < nums.length;i++) {
//Determine if duplicate elements exist
if(track.contains(nums[i]))
continue;
//add to the path
track.add(nums[i]);
//backtrack
baketrack(nums, track);
//remove the element
track.removeLast();
}
}
}