力扣题目:
题目链接: 491.非递减子序列
参考题解: 代码随想录
题目描述
代码思路
这道题关键是排除重复的子序列,同一父节点下的同层上使用过的元素就不能再使用了
代码纯享版
class Solution {
public List<List<Integer>> list_all = new ArrayList();
public List<Integer> list = new ArrayList();
public List<List<Integer>> findSubsequences(int[] nums) {
backtrack(nums, 0);
return list_all;
}
void backtrack(int[] nums, int start){
if(list.size() >= 2) list_all.add(new ArrayList(list));
Set<Integer> set = new HashSet();
for(int i = start; i < nums.length; i++){
if((list.size() != 0 && list.get(list.size() - 1) > nums[i]) || set.contains(nums[i])){
continue;
}
list.add(nums[i]);
set.add(nums[i]);
backtrack(nums, i + 1);
list.remove(list.size() - 1);
}
}
}
代码逐行解析版
class Solution {
public List<List<Integer>> list_all = new ArrayList();
public List<Integer> list = new ArrayList();
public List<List<Integer>> findSubsequences(int[] nums) {
backtrack(nums, 0);
return list_all;
}
void backtrack(int[] nums, int start){
if(list.size() >= 2) list_all.add(new ArrayList(list)); //子序列长度大于2时,将list添加到list_all中
Set<Integer> set = new HashSet(); //创建set集合
for(int i = start; i < nums.length; i++){
//剪枝:两种情况直接跳出本轮循环
//1.子序列长度不为0且子序列最后一位大于要添加到元素
//2.集合中已经有这个元素(同层中第二个相同的元素所形成的序列已经在第一个元素中出现过)
if((list.size() != 0 && list.get(list.size() - 1) > nums[i]) || set.contains(nums[i])){
continue;
}
list.add(nums[i]); //将数组元素添加到子序列list
set.add(nums[i]); //将添加到元素添加到set集合中
backtrack(nums, i + 1); //递归到下一层,start=i+1
list.remove(list.size() - 1); //回溯,删掉子序列list中最后一个元素
}
}
}