题目分析
- dfs 需要一层一层地来,画一个竖的表格
- 记录每一层干什么;记录结束时的条件
- 注意用过的就不能再选了,所以要记录每次要添加的列表,判断如果要加入的元素已经在其中,就直接跳过
- 当添加完一种情况后,注意把记录使用过的,在标记为没用过
Solution
private List<List<Integer>> list;
private int[] nums;
/** 用来保存每一层选择的数字 */
private List<Integer> result;
public List<List<Integer>> permute(int[] nums) {
if (nums == null) return null;
list = new ArrayList<>();
if (nums.length == 0) return list;
this.nums = nums;
result = new ArrayList<>();
dfs(0);
return list;
}
private void dfs(int idx) {
// 不能再往下搜索
if (idx == nums.length) {
// 注意创建一个新对象
list.add(new ArrayList<>(result));
return;
}
// 枚举这一层所有可以做出的选择
for (int num : nums) {
if (result.contains(num)) continue;
result.add(num);
dfs(idx + 1);
// 还原现场
result.remove(result.size() - 1);
}
}
Solution 2
相当于定0位置为1、2、3,分别找可能的情况
流程:
- 第0层:让0位置和0、1、2位置进行交换(相当于让第0位置出现每个位置的数字)
- 第1层:让1位置和1、2位置进行交换
public List<List<Integer>> permute(int[] nums) {
if (nums == null) return null;
List<List<Integer>> list = new ArrayList<>();
if (nums.length == 0) return list;
dfs(0, nums, list);
return list;
}
private void dfs(int idx, int[] nums, List<List<Integer>> list) {
// 不能再往下搜索
if (idx == nums.length) {
List<Integer> result = new ArrayList<>();
for (int value : nums) {
result.add(value);
}
list.add(result);
return;
}
// 枚举这一层所有可以做出的选择
for (int i = idx; i < nums.length; i++) {
swap(nums, idx, i);
dfs(idx + 1, nums, list);
swap(nums, idx, i);
}
}
private void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
Reference:小码哥MJ