LeetCode算法学习之--Recursion--组合

199 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

大家好今天给大家分享下一道 LeetCode 中等难度 的题目[77. 组合]

image.png (图片转载leetcode)

题目

给定两个整数 nk,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

分析

1.每个组合的取值范围是【1,n】

2.每个组合最多k个元素,组合中的元素不能重复

3.返回一个二维数组 且不能有重复的值

解法

1.暴力法

2.递归+条件递归

解法一:暴力 (无法通过)

思路
1.求出所有的可能值
2.去重复
*/
​
var combine = function (n, k) {
  const res = [];
  generateAll([]);
​
  //   通过递归生成所有的可能值
  function generateAll(arr) {
    //   终止条件是arr的长度===k了
    if (arr.length === k) {
      res.push(arr);
      return;
    }
    for (let i = 1; i <= n; i++) {
      // 因为每个组合中元素不能一样,所以先判断能否添加到组合中
      !arr.includes(i) && generateAll([...arr, i]);
    }
  }
​
  //   通过hashMap 来去重复值
  function removeDuplicate(arr) {
    const map = new Map();
​
    for (const item of arr) {
      item.sort();
      map.set(item.join(","), item);
    }
​
    return Array.from(map.values());
  }
​
  return removeDuplicate(res);
};
​
/* 复杂度
时间 O(n^k)
空间 O(n*k)
*/

解法二:条件递归

思路
1.因为暴力的方法无法通过,所以需要在进入递归的时候进行条件的筛选,只有满足以下2个条件的才递归
 1.i>m 表示要新添加的元素必须大于之前的元素,这样就能保证无重复
 2.!arr.includes(i) 当前数组中没有这个元素
*/
​
var combine = function (n, k) {
  const res = [];
​
  function recur(m, arr) {
    //   终止条件是arr的长度===k了
    if (arr.length === k) {
      res.push(arr);
      return;
    }
    for (let i = 1; i <= n; i++) {
      //   只有满足以下2个条件的才递归
      !arr.includes(i) && i > m && recur(i, [...arr, i]);
    }
  }
​
  //   开始的时候给一个初始值0
  recur(0, []);
  return res;
};
​
​

总结

今天这道题是主要是练习递归的方式来处理生成元素类的题目

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

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

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

\