前言
“这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战”
- 46. 全排列
- NC42 有重复项数字的所有排列(中等)
46. 全排列
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例 2: 输入:nums = [0,1] 输出:[[0,1],[1,0]]
示例 3: 输入:nums = [1] 输出:[[1]]
提示:
1 <= nums.length <= 6
-10 <= nums[i] <= 10
nums 中的所有整数 互不相同
思路分析:
回溯问题主要关心3点
- 已经做出的选择(记录在 temp 中)
- 结束条件(temp 中元素的个数 等于 数组的长度)
- 可以做出的选择(未在temp 中出现的元素)
AC 代码:
List<List<Integer>> ans = new ArrayList<>();
public List<List<Integer>> permute(int[] nums) {
dfs(nums, new ArrayList<>());
return ans;
}
void dfs(int[] nums, List<Integer> temp) {
if (temp.size() == nums.length) {
ans.add(new ArrayList<>(temp));
return;
}
for (Integer num : nums) {
if (!temp.contains(num)) {
temp.add(num);
dfs(nums, temp);
temp.remove(temp.size() - 1);
}
}
}
有重复项数字的所有排列
给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
NC42 与leetcode 上的 47 题一样 47. 全排列 II
示例 1:
输入:nums = [1,1,2] 输出: [[1,1,2], [1,2,1], [2,1,1]]
示例 2:
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
思路分析:
存在重复的元素, 因此首先对数组排序, 其次在回溯的过程中 剪枝, 同一层不重复选择
与子集中剪枝一样 回溯问题主要关心3点
- 已经做出的选择(记录在 temp 中)
- 结束条件(temp 中元素的个数 等于 数组的长度)
- 可以做出的选择(同一层不存在重复的选择&&未使用的元素)
AC 代码:
ArrayList<ArrayList<Integer>> ans = new ArrayList<>();
boolean[] used;
public ArrayList<ArrayList<Integer>> permuteUnique(int[] nums) {
used = new boolean[nums.length];
Arrays.sort(nums);
dfs(nums, new ArrayList<>());
return ans;
}
void dfs(int[] nums, ArrayList<Integer> temp) {
if (temp.size() == nums.length) {
ans.add(new ArrayList<>(temp));
return;
}
for (int i = 0; i < nums.length; i++) {
int num = nums[i];
if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) continue;
if (!used[i]) {
temp.add(num);
used[i] = true;
dfs(nums, temp);
used[i] = false;
temp.remove(temp.size() - 1);
}
}
}