78--子集
题目

题解:
varsubsets=function(nums) {
// 子集是收集每个节点的结果
letpath=[],res=[]
letlen=nums.length
backtracking(0)
returnres
functionbacktracking(startIndex){
//path.slice()指的是path的所有元素(当slice不妨任何参数的时候)
res.push(path.slice())
for(leti=startIndex;i<len;i++){
path.push(nums[i])
backtracking(i+1)
path.pop()
}
}
};
90--子集II
题目

题解:
varsubsetsWithDup=function(nums) {
// 由于nums中可能会包含重复的元素,但是解集中又不能返回重复的子集
// 故我们需要对其进行一个去重操作
// 在做去重前,我们还要做的是对nums进行一个排序
// 其次,我们做这种回溯题的时候,最好对nums进行一个排序,为了方便树的走向
// 1,排序
nums=nums.sort((a,b)=>a-b)
letres= [],path=[]
letlen=nums.length
backtracking(0)
returnres
functionbacktracking(startIndex){
// path.slice()指的是path的所有元素(当slice不妨任何参数的时候)
//其中 path.slice()==》Array.from(path) 二者作用相同,把path里的所有元素重新组成一个新的元素 //传到res中
res.push(path.slice())
for(leti=startIndex;i<len;i++){
// 去重
if(i>startIndex&&nums[i]==nums[i-1]){
continue
}
path.push(nums[i])
backtracking(i+1)
path.pop()
}
}
其中 path.slice()==》Array.from(path) 二者作用相同,把path里的所有元素重新组成一个新的元素 //传到res中
};
知识点
其中 path.slice()==》Array.from(path) 二者作用相同,把path里的所有元素重新组成一个新的元素 //传到res中
全排列
题目

题解:
varpermute=function(nums) {
// res存储总的答案,path存储每一层循环得到的答案
letres= [],path=[]
letused= []
k=nums.length;
backtracking(nums,k,used)
returnres;
// nums存储原数组,k存储的是数组长度,used标识已经用过的数组元素
functionbacktracking(nums,k,used){
// 一次节点循环的条件==当path的长度达到了题目所要求的长度,即跟原数组长度相同,就可以把这个数组元素推入到res中
if(path.length===k){
res.push([...path]) //[...path]将数组元素path展开之后推入到
return;
}
for(leti=0; i<k; i++){
if(used[i])continue//如果此时的nums[i]等于true,表明已经标识过了,不应用它
path.push(nums[i])
used[i]=true
backtracking(nums,k,used);
path.pop() //要删除path中最后一个元素,让它完成树的开枝
used[i]=false
}
}
};
组合与排列
组合是不能出现 [1,2] 和 [2,1] 这种情况的,因此需要用一个startIndex去避免重复用到前一个元素排列过的值
排列是可以出现 [1,2] 和 [2,1] 这种情况的,但是为了避免一个组合里同一个元素出现太多次,则需要设立一个 used 数组,去比对是否有已经用过的元素,相当于去重操作