小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
大家好今天给大家分享下一道 LeetCode 中等难度 的题目[77. 组合]
(图片转载leetcode)
题目
给定两个整数
n
和k
,返回范围[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
\