题目描述
// 46. 全排列
// 给定一个 没有重复 数字的序列,返回其所有可能的全排列。
题解
// 回溯搜索
//
// 跟【Leetcode】39. 组合总和 很像,但又不一样,这里的排列组合需要反复用到nums中各个位置
// 的元素,所以我们不需要设定回溯搜索的起始位来限制搜索范围,
// 相反我们不限制搜索范围,每一次搜索都要扫描一遍nums中的元素。
// 但同时排列组合不能重复使用元素,因此我们设定一个元素使用标记boolean[] used,
// used与nums同大小,如果nums中i索引位元素被使用,则used中i索引位布尔值为true,
// 没被使用则为false。其他地方就跟39很像了,定义答案保存位res,
// 定义组合数组combination,当combination存满了就存入res。
//
// 定义回溯搜索函数backtracking,老样子,先规定递归的终止条件,
// 如果combination已经存满了(size()等于nums长度),则将combination存入res中,
// 然后返回。
// for循环从头到尾遍历nums中的元素记为nums[i],如果used[i]位的boolean为true,
// 表示nums[i]已经被使用,continue跳过nums[i]这个数。
// 否则,则将nums[i]存入combination中,令used中的i索引位标记为true,
// 然后递归调用backtracking继续回溯搜索下一个元素。
// 当递归返回之后我们删除刚刚存入的nums[i],将used的i位重新置为false。
//
// 执行用时:1 ms, 在所有 Java 提交中击败了96.72%的用户
// 内存消耗:38.6 MB, 在所有 Java 提交中击败了70.52%的用户
class Solution {
public List<List<Integer>> permute(int[] nums) {
boolean[] used = new boolean[nums.length];
List<List<Integer>> res = new ArrayList<>();
List<Integer> combination = new ArrayList<>();
backtracking(nums, res, combination, used);
return res;
}
private void backtracking(int[] nums, List<List<Integer>> res, List<Integer> combination, boolean[] used) {
if (combination.size() == nums.length) {
res.add(new ArrayList<>(combination));
return;
}
for (int i = 0; i < nums.length; i++) {
if (used[i]) continue;
combination.add(nums[i]);
used[i] = true;
backtracking(nums, res, combination, used);
combination.remove(combination.size() - 1);
used[i] = false;
}
}
}