LeetCode46-全排列
一、题目描述
二、回溯树
常见的排列问题的回溯树一般有两种写法,下面给出了相应的图示:
2.1 基于swap的回溯树
树的深度每加深一层,那么该层的每个结点的分支将会减少1,比如第0层是3个分支,到了第1层,每个结点就只有两个分支
2.2 基于visited数组的回溯树
每一层依然是扩展三个结点,但是重复的结点将会被剪枝,这样也会得到排列问题的回溯树
三、代码实现
3.1 基于swap回溯树的代码
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
solve(nums, 0, res);
return res;
}
public void solve(int[] nums, int startIndex, List<List<Integer>> res) {
if (startIndex >= nums.length) {
List<Integer> curRes = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
curRes.add(nums[i]);
}
res.add(curRes);
return;
}
for (int i = startIndex; i < nums.length; i++) {
swap(nums, i, startIndex);
solve(nums, startIndex + 1, res);
swap(nums, i, startIndex);
}
}
private void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
3.2 基于visited数组回溯树的代码
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
boolean[] visited = new boolean[nums.length];
solve(nums, 0, res, new ArrayList<>(), visited);
return res;
}
public void solve(int[] nums, int startIndex, List<List<Integer>> res, List<Integer> curRes, boolean[] visited) {
if (startIndex == nums.length) {
res.add(new ArrayList<>(curRes));
return;
}
for (int i = 0; i < nums.length; i++) {
if (visited[i]) {
continue;
}
curRes.add(nums[i]);
visited[i] = true;
solve(nums, startIndex + 1, res, curRes, visited);
curRes.remove(curRes.size() - 1);
visited[i] = false;
}
}
}