LeetCode算法学习之--分治--78.子集

237 阅读2分钟

「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

大家好今天给大家分享一道 LeetCode 中等难度 的题目78. 子集

题目

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

image.png (图片来自leetcode)

分析

1.数组无重复值

2.不能包含重复的子集

3.返回二维数组

解法

1.递归

2.迭代

解法一:递归

思路
这道题的子集可以理解为, 一个集合中 选择或者 不选nums中的每个数,所以子集的个数是2^n
​
1.终止条件:当cur的值等于nums.length的时候 说明所有nums里面的值都已经判断选还是不选了,
所以当前的arr就是最终的答案之一
2.每个递归中,cur+1且分两种情况递归 
 1.recur(cur + 1, nums, [...arr, element]); 代表选择了当前的元素
 2.recur(cur + 1, nums, arr); 代表不选择当前元素
*/
​
var subsets = function (nums) {
  if (!nums.length) return [];
​
  const res = [];
  function recur(cur, nums, arr) {
    // 终止条件:当cur的值等于nums.length的时候
    if (cur === nums.length) {
      res.push(arr);
      return;
    }
    const element = nums[cur];
    // 代表选择了当前的元素
    recur(cur + 1, nums, [...arr, element]);
    // 代表不选择当前元素
    recur(cur + 1, nums, arr);
  }
​
  recur(0, nums, []);
​
  return res;
};
/* 复杂度
时间 O(2^n*n)
空间 O(n)
*/

解法二:迭代

思路
1.迭代的思路和递归差不多,只是运行的方式不一样。
2.先初始化一个res数组[[]],其中的[]代表什么都没有选的情况
3.然后再迭代每个nums里面的数,分别去拼装 res中的各个集合。
4.最终得到的结果就是子集
*/
var subsets = function (nums) {
  if (!nums.length) return [];
​
  const res = [[]];
​
  for (let i = 0; i < nums.length; i++) {
    const num = nums[i];
    const length = res.length;
    for (let j = 0; j < length; j++) {
      res.push([...res[j], num]);
    }
  }
​
  return res;
};
/* 复杂度
时间 O(2^n*n)
空间 O(n)
*/

总结

今天这道题是主要是练习使用递归和迭代的方式来实现子集生成这类的分治算法

大家可以看看我分享的一个专栏(前端搞算法)里面有更多关于算法的题目的分享,希望能够帮到大家,我会尽量保持每天晚上更新,如果喜欢的麻烦帮我点个赞,十分感谢

大家如果对“TS”感兴趣的可以看看我的专栏 (TypeScript常用知识),感谢大家的支持

文章内容目的在于学习讨论与分享学习算法过程中的心得体会,文中部分素材来源网络,如有侵权,请联系删除,邮箱 182450609@qq.com

\