第一种递归,for循环选择不同的数字(可以在选择途中,将符合要求的子序列加入结果集中)
// 第一种dfs,耗时15ms,在每次取元素时就判断是否为所求。
public static void dfs1(int[] nums, int idx, List<Integer> list) {
// 在每次取元素时就判断是否为所求。
if (list.size() >= 2) {
// if (!res.contains(list)) { //res判重时间复杂度太高
// res.add(new ArrayList<>(list));
// }
set.add(new ArrayList<>(list));
}
if (idx == nums.length) {
return;
}
for (int i = idx; i < nums.length; i++) {
if (list.size() == 0 || nums[i] >= list.get(list.size() - 1)) {
list.add(nums[i]);
dfs1(nums, i + 1, list);
list.remove(list.size() - 1);
}
}
}
第二种选择递归一定要到截止条件,才将符合要求的子序列加入结果集中。
// 第二种dfs,每个元素都有选择与不选的可能,直到idx为边界时再判断。
public static void dfs2(int[] nums, int idx, List<Integer> list) {
if (idx >= nums.length) {
if (list.size() >= 2) {
set.add(new ArrayList<>(list));
}
}
if (list.size() == 0 || nums[idx] >= list.get(list.size() - 1)) {
list.add(nums[idx]);
dfs2(nums, idx + 1, list);
list.remove(list.size() - 1);
}
// 不选择idx的元素
dfs2(nums, idx + 1, list);
}
调用函数代码如下:
// 491. 递增子序列
static List<List<Integer>> res;
static HashSet<List<Integer>> set = new HashSet<>();
public static List<List<Integer>> findSubsequences(int[] nums) {
if (nums == null || nums.length == 0) {
res = new ArrayList<>();
return res;
}
List<Integer> list = new ArrayList<>();
dfs1(nums, 0, list);
res = new ArrayList<>(set);
return res;
}