[LeetCode:subsets] | 刷题打卡

352 阅读1分钟

真心求大家关注和点赞,原创不易,你们的支持是我写作的最大动力!

题目描述

给你一个整数数组 nums,nums 中所有数字唯一,返回所有可能的子集,结果中子集不能重复,顺序任意

例一:

输入: nums = [1,2,3]
输出: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

例二:

输入: nums = [0]
输出: [[],[0]]

思路分析

这也是一道考察回溯算法的题目,参考 Letter Combinations of a Phone Number 中写递归的思路,分析如下:

回溯函数的参数一般为:待选数组集合和已选择的值。但是这题需要返回所有的子集,长度从 0 到 nums.length 不等,所以参数除了这两个以外,还需要一个 k 用来判断当前子集的长度,我们需要得到长度为 0,1,2...nums.length 的所有可能结果。

for (let i = 0; i < nums.length; i++) {
  backtrace(nums, [], i + 1);
}

初始化时:

  • 待选数组就是 nums
  • 已选择的很明显是空
  • 我们需要计算各种长度的字集,所以要对 nums 进行遍历

回溯算法体:

const backtrace = (arr, current, k) => {};

遍历 arr 待选数组,把每次遍历的结果和当前已选的内容拼接成一个新的数组传入下一次递归,相应的 k 也就减 1

递归出口:k 减少到 0。此时我们需要将 cur 的值 push 到结果数组 result 中

AC 代码

var subsets = function (nums) {
  const result = [[]];
  const backtrace = (arr, current, k) => {
    if (k === 0) {
      result.push(current);
      return;
    }
    for (let i = 0; i < arr.length; i++) {
      backtrace(arr.slice(i + 1), [...current, arr[i]], k - 1);
    }
  };
  for (let i = 0; i < nums.length; i++) {
    backtrace(nums, [], i + 1);
  }
  return result;
};

总结

这道题和 Letter Combinations of a Phone Number 的区别可能就在于初始化,前者需要在初始化时执行遍历,拿到所有长度为 k 的子集,而后者则不需要

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情