ts算法题解(第37天)----leetcode78. 子集

169 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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(选择列表,路径)
        从路径中撤销    
    }
}

不过这个模板是全排列的模板

有什么区别呢?

image.png

全排列是元素无重可复选

而我们的子集是元素无重不可复选

image.png

子集的图是这个样子的,所以为了不可复选,我们需要一个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们,快来试试把

参考