题目:46. 全排列
思路:回溯。
- 新建一个visited数组,表示数字是否使用过。
- 不使用额外的空间,用原本数字记录是否使用过。这个官方题解 讲的很清楚。把原数组看作2部分,左侧是已经访问过的数字,右侧是待访问的数字。记录当前需要放数字的位置,然后不断交换当前位置的数字与待访问的数字。
代码:
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> aim = new ArrayList<>();
boolean[] visited = new boolean[nums.length];
backtrack(nums, visited, aim, res);
return res;
}
public void backtrack(int[] nums, boolean[] visited, List<Integer> aim, List<List<Integer>> res) {
if (aim.size() == nums.length) {
res.add(new ArrayList<>(aim));
return;
}
for (int i = 0; i < nums.length; i++) {
if (visited[i]) {
continue;
}
aim.add(nums[i]);
visited[i] = true;
backtrack(nums, visited, aim, res);
aim.remove(aim.size() - 1);
visited[i] = false;
}
}
}
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> aim = new ArrayList<>();
for (int i : nums) {
aim.add(i);
}
backtrack(aim, 0, nums.length, res);
return res;
}
public void backtrack(List<Integer> nums, int cur, int n, List<List<Integer>> res) {
if (cur == n) {
res.add(new ArrayList<Integer>(nums));
return;
}
for (int i = cur; i < n; i ++) {
Collections.swap(nums, cur, i);
backtrack(nums, cur + 1, n, res);
Collections.swap(nums, cur, i);
}
}
}