一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情。
前言
每天一道算法题,死磕算法
题目
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入: nums = [1,2,3]
输出: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
分析
先来上模板
- 1.路径(track):也就是已经做出的选择
- 2.选择列表(nums):也就是你当前可以做的选择
- 3.结束条件:也就是无法在做选择的条件
result = [];
let backTrack = function(选择列表,路径){
if(满足条件){
result.push(路径);
return;
}
for(选择 in 选择列表){
添加到路径中
backTrack(选择列表,路径)
从路径中撤销
}
}
不过这个模板是全排列的模板
有什么区别呢?
全排列是元素无重可复选
而我们的子集是元素无重不可复选
子集的图是这个样子的,所以为了不可复选,我们需要一个start参数来控制树的生长
所以子集这种题目的模板是这个样子的
function backTrack(track:number[], nums:number[], start:number, result) {
// 把所有结果都放到结果中
result.push(track.slice());
// start来控制树的生长
for (let i = start; i < nums.length; i++){
track.push(nums[i]);
backTrack(track, nums, i + 1, result);
track.pop();
}
}
start是如何来控制树的生长的呢?
第一行start为0,把start赋值给i,所以第一层能取到1(此时i为0),2(此时i为1),3(此时i为2)
第二行第一列,start为0,所以能取到2(此时i为1),3(此时i为2)
第二行第二列,start为1,所以只能取到3(此时i为2)
第二行第三列,start为2,取不到值了,因为不满足for循环条件
第三行第一列,start为1,所以能取到3(此时i为2)
第三行第二列,start为2,取不到值了,因为不满足for循环条件
后面的也都取不到了,这就是用start控制生长
题解
function backTrack(track:number[], nums:number[], start:number, result:number[][]) {
// start来控制树的生长
result.push(track.slice());
for (let i = start; i < nums.length; i++){
track.push(nums[i]);
backTrack(track, nums, i + 1, result);
track.pop();
}
}
function subsets(nums: number[]): number[][] {
let result = [];
backTrack([], nums, 0, result);
return result;
};
亲爱的jy们,快来试试把