记录了LeetCode最经典的46、47、78、90四道题,首先从无重复的情况开始学习,进而改进代码,满足去重的要求。这里的dfs确切的说是回溯(backtrack)。
Combination 无重复
Combination 组合
- 无重复
LeetCode 78
下面的两种方法都是通过 回溯 解决的,输出顺序不同。从个人记忆面试出发,我选择了第一种。
//dfs 不使用for循环
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new LinkedList<>();
if (nums == null || nums.length == 0) {
return res;
}
LinkedList<Integer> list = new LinkedList<>();
dfs(nums, 0, res, list);
return res;
}
private void dfs(int[] nums, int position, List<List<Integer>> res, LinkedList<Integer> list) {
//出口
if (position == nums.length) {
res.add(new LinkedList(list));
return;
}
list.add(nums[position]);
dfs(nums, position+1, res, list);
list.removeLast();
dfs(nums, position+1, res, list);
}
}
//dfs 使用for循环
// class Solution {
// public List<List<Integer>> subsets(int[] nums) {
// List<List<Integer>> res = new LinkedList<>();
// if (nums == null || nums.length == 0) {
// return res;
// }
// LinkedList<Integer> list = new LinkedList<>();
// dfs(nums, 0, res, list);
// return res;
// }
// private void dfs(int[] nums, int position, List<List<Integer>> res, LinkedList<Integer> list) {
// res.add(new LinkedList(list));
// for (int i = position; i < nums.length; i++) {
// list.add(nums[i]);
// dfs(nums, i+1, res, list);
// list.removeLast();
// }
// }
// }
Combination 有重复
- 有重复,需要去重
LeetCode 90
由于有重复元素,要注意在回溯之前进行排序。
这里使用了LinkedHashSet和普通的LinkedList,其实都是对结果去重,没什么区别。
//去重,LinkedHashSet
// class Solution {
// public List<List<Integer>> subsetsWithDup(int[] nums) {
// Set<List<Integer>> res = new LinkedHashSet<>();
// if (nums == null || nums.length == 0) {
// return new ArrayList<>(res);
// }
// LinkedList<Integer> list = new LinkedList<>();
// Arrays.sort(nums);
// dfs(nums, 0, res, list);
// return new ArrayList<>(res);
// }
// private void dfs(int[] nums, int position, Set<List<Integer>> res, LinkedList<Integer> list) {
// //出口
// if (position == nums.length) {
// res.add(new LinkedList(list));
// return;
// }
// list.add(nums[position]);
// dfs(nums, position+1, res, list);
// list.removeLast();
// dfs(nums, position+1, res, list);
// }
// }
//去重,ArrayList
class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> res = new LinkedList<>();
if (nums == null || nums.length == 0) {
return res;
}
LinkedList<Integer> list = new LinkedList<>();
Arrays.sort(nums);
dfs(nums, 0, res, list);
return res;
}
private void dfs(int[] nums, int position, List<List<Integer>> res, LinkedList<Integer> list) {
//出口
if (position == nums.length) {
if (!res.contains(new LinkedList(list))) {
res.add(new LinkedList(list));
}
return;
}
list.add(nums[position]);
dfs(nums, position+1, res, list);
list.removeLast();
dfs(nums, position+1, res, list);
}
}
Permutation 排列
- 无重复
LeetCode 46
对于全排列的题,使用了for循环,并要求选数时不能选“自己”。
class Solution {
public List<List<Integer>> permute(int[] nums) {
//结果集
List<List<Integer>> res = new LinkedList<>();
if (nums == null || nums.length == 0) {
return res;
}
LinkedList<Integer> track = new LinkedList<>();
dfs(nums, res, track, 0);
return res;
}
private void dfs(int[] nums, List<List<Integer>> res, LinkedList<Integer> track, int position) {
//终止条件
if (position == nums.length) {
res.add(new LinkedList(track));
return;
}
for (int i = 0; i < nums.length; i++) {
//不重复
if (track.contains(nums[i])) {
continue;
}
track.add(nums[i]);
dfs(nums, res, track, position+1);
track.removeLast();
}
}
}
- 有重复,需要去重
LeetCode 47
对于这道题,需要再加一个marked的数组用来标记了(其实前面的题也可以使用marked,省去contains),理解起来不难。
注意判断条件。
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
//结果集
List<List<Integer>> res = new LinkedList<>();
if (nums == null || nums.length == 0) {
return res;
}
LinkedList<Integer> track = new LinkedList<>();
boolean[] marked = new boolean[nums.length];
Arrays.sort(nums);
dfs(nums, res, track, 0, marked);
return res;
}
private void dfs(int[] nums, List<List<Integer>> res, LinkedList<Integer> track, int position, boolean[] marked) {
//终止条件
if (position == nums.length) {
res.add(new LinkedList(track));
return;
}
for (int i = 0; i < nums.length; i++) {
if (!marked[i] && (i == 0 || nums[i-1] != nums[i] || marked[i-1])) {
track.add(nums[i]);
marked[i] = true;
dfs(nums, res, track, position+1, marked);
track.removeLast();
marked[i] = false;
}
}
}
}