题目:递增子序列
题目描述:
给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。
示例:
输入: [4, 6, 7, 7]
输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]
说明:
给定数组的长度不会超过15。
数组中的整数范围是 [-100,100]。
给定数组中可能包含重复数字,相等的数字应该被视为递增的一种情况。
解题思路:
ps:参考力扣评论区
这道题的难度在于数字会重复,先考虑没有重复的情况
加入当前数字会产生哪些新序列,只要遍历当前存在的序列并比较最后一个数字和当前数字,如果当前数字更大则加入产生新的序列
由 1 产生的新序列加上已经存在的序列以及当前数字作为一个新序列起点的情况作为新的结果
最后过滤掉长度不足 2 的序列得到最终结果
加入重复数字后,比如序列 [4,6,7,7] 遍历完前三个数字后可得到
[[4],[4,6],[6],[4,7],[4,6,7],[6,7],[7]],再加入 7 的话与前三个的组合就会和后面发生重复,所以要避免与前三个组合。利用字典保存该数字上一次出现时未组合之前结果的长度,当再次出现时只和该索引以及之后的序列进行组合,这样就避免了重复。最后去掉长度不足 2 的序列。
代码实现:
class Solution {
//回溯法进行求解,当后面的值大于前面的值时,把元素往集合中进行添加
Set<List<Integer>> list=new HashSet<>();
public List<List<Integer>> findSubsequences(int[] nums) {
//List<List<Integer>> list=new ArrayList<>();
List<Integer> al=new ArrayList<>();
getRes(al,nums,0);
return new ArrayList<>(list);
}
private void getRes(List<Integer> al, int[] nums, int start) {
if(al.size()>=2) {
List<Integer> cloneAl=new ArrayList<>(al);
list.add(cloneAl);
}
for(int i=start;i<nums.length;i++) {
if(al.size()==0 || nums[i]>=al.get(al.size()-1)) {
//如果此时的值比前一个值大的话,添加到集合中
al.add(nums[i]);
getRes(al,nums,i+1);
al.remove(al.size()-1);
}
}
}
}
ps: 不能使用List ,用它进行contains去除重复时会超时。