491--递增子序列
题目

分析
一般来说正常的回溯题都是最好先排序,但是此题要求的题解是递增子序列,所以不能第一步就排序,回溯排序的目的是为了我们方便搜索树
此题还有一点树的每一层递归,要做到去重,就是每一层用过的元素,不能再用第二次,因此,我们可以多设置一个 new Set(),来判定是否这一层的递归有用过这个元素
es6--new Set()
类似数组,但它的一大特性就是所有元素都是唯一的,没有重复的。可以利用这一特性进行数组的去重工作。
常用方法
添加元素 add()
let list=new Set();
list.add(1)
删除元素 delete(),删除数值
判断某元素是否存在 has(),有返回true,无返回false
清除所有元素 clear()
遍历 keys()
letlist2=newSet(['a','b','c'])
for(letkeyoflist2.keys()){
console.log(key)//a,b,c
}
遍历 values()
letlist=newSet(['a','b','c'])
for(letvalueoflist.values()){
console.log(value)//a,b,c
}
遍历 foreach()
letlist=newSet(['4','5','hello'])
list.forEach(function(item){
console.log(item)
})
数组转set(用于数组去重)
letset2=newSet([4,5,6])
set转数组
letset4=newSet([4, 5, 6])
//方法一 es6的...解构
letarr1= [...set4];
//方法二 Array.from()解析类数组为数组
letarr2=Array.from(set4)
题解
varfindSubsequences=function(nums) {
// 此题的要求是不能排序
letres=[],path=[]
letlen=nums.length
backtracking(0)
returnres
functionbacktracking(startIndex){
if(path.length>1){
res.push(Array.from(path))
}
// 这里 new Set(),目的是为了记录这一层递归的时候是否出现过,因为每一层递归的元素不能重复
letsetPath=newSet()
for(leti=startIndex;i<len;i++){
// 2.去重,如果有重复的元素,就跳过这个元素,进行下一个元素的搜索
if(path.length>0&&nums[i]<path[path.length-1]||setPath.has(nums[i])){
continue
}
// 给满足以上条件的元素添加到 刚刚 建的setPath中,
// 那么为什么不用像path一样清除它呢
// 因为每一层递归结束后,我们这第一轮for循环都会结束,然后重新传参,进行下一层的递归,
// 在进行下一层的递归前,又重新定义了一个 new Set()
// 做到了这个setPath中只记录本层的元素,检验本层元素是否有重复使用过,
// 而不是检查整一个树是否有重复使用过这个元素
setPath.add(nums[i])
path.push(nums[i])
backtracking(i+1)
path.pop()
}
}
};