leetcode 77. 组合 思考分析
目录
- 1、题目
- 2、回溯法思路
- 3、参考其他思路,更深入了解这个问题
- 4、剪枝优化
可能需要回顾到的知识文章:
1、常用算法总结(穷举法、贪心算法、递归与分治算法、回溯算法、数值概率算法)
2、回溯法初步
删除vector容器中的对象元素的三种方法:pop_back, erase与remove算法
1、题目
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
2、回溯法思路
集合元素个数为n,由此可以看出解空间树每个结点有n孩子,深度为k。
利用模板,就就就AC了。。。
每次确定一个起点和一个终点,从start遍历到end(对于本层元素而言)。
将第i个元素放入res中,然后进入下一层,下一层的起点是i+1(这样start只会一直向大的数值延伸,不会产生重复的元素)。
如果不符合就把这个元素pop掉。
class Solution {public:vector<vector<int>> result;vector<int> res;void backtracking(int start,int end,int k){//找到了k个数if(res.size() == k){result.push_back(res);return;}for(int i=start;i<=end;i++){//处理结点;res.push_back(i);//递归,探索下一层backtracking(i+1,end,k); //递归//回溯,撤销处理结果res.pop_back();}}vector<vector<int>> combine(int n, int k) {result.clear();res.clear();backtracking(1,n,k);return result;}
};
3、参考其他思路,更深入了解这个问题
对于较小的k,我们可以很容易想到for循环嵌套k层解决,如下:
n=4,k=2;
int n = 4;
for (int i = 1; i <= n; i++) {for (int j = i + 1; j <= n; j++) {cout << i << " " << j << endl;}
}
但是对于较大的k,我们的显然不能写嵌套for。例如要解决n=100.k=50的情况,暴力写法需要嵌套50层for循环,而回溯法就是利用递归来解决嵌套层数的问题。
每一层递归中嵌套一个for循环,那么递归就可以用于解决多层嵌套循环的问题了。
观察我们的解空间树:
每次从集合中选取元素,可选择的范围随着选择的进行而收缩,调整可选择的范围。
n相当于树的宽度,k相当于树的深度。
4、剪枝优化
下面的遍历范围是可以剪枝优化的:
for(int i=start;i<=end;i++)
{//处理结点;res.push_back(i);//递归,探索下一层backtracking(i+1,end,k); //递归//回溯,撤销处理结果res.pop_back();
}
举例n=4,k=4时,那么第一层for循环的时候,从元素2开始的遍历就已经没有意义了,因为遍历了也凑不到4个元素了。
所以我们可以剪枝的地方就是每一层的end。
我们已经选择的元素个数为:res.size()
我们还需要的元素的个数为k-res.size()
所以最多从end-(k-res.size())+1
的地方开始遍历。
所以可以修改为:
for(int i=start;i<=end-(k-res.size())+1;i++)
{//处理结点;res.push_back(i);//递归,探索下一层backtracking(i+1,end,k); //递归//回溯,撤销处理结果res.pop_back();
}
完整代码:
class Solution {public:vector<vector<int>> result;vector<int> res;void backtracking(int start,int end,int k){//找到了k个数if(res.size() == k){result.push_back(res);return;}for(int i=start;i<=end-(k-res.size())+1;i++){//处理结点;res.push_back(i);//递归,探索下一层backtracking(i+1,end,k); //递归//回溯,撤销处理结果res.pop_back();}}vector<vector<int>> combine(int n, int k) {result.clear();res.clear();backtracking(1,n,k);return result;}
};
可以看到速度是有明显的提升的:
leetcode 77. 组合 思考分析相关推荐
- LeetCode.77. 组合
LeetCode.77. 组合 难度:中等 这道题属于回溯的经典题目: 回溯模板: void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择:本层集 ...
- leetcode 78. 子集 思考分析
题目 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 思考分析 画出解空间树. 我们可以发现我们所需要的结果是解空间的所有结点.而我们之前 ...
- leetcode:77.组合
77. 组合 来源:力扣(LeetCode) 链接: https://leetcode.cn/problems/combinations 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 ...
- LeetCode 77. 组合 | Python
77. 组合 题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/combinations 题目 给定两个整数 n 和 k,返回 1 - n 中所有可能 ...
- Java实现 LeetCode 77 组合
77. 组合 给定两个整数 n 和 k,返回 1 - n 中所有可能的 k 个数的组合. 示例: 输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], ...
- LeetCode 110. 平衡二叉树思考分析
题目 给定一个二叉树,判断它是否是高度平衡的二叉树. 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1. 示例 1: 给定二叉树 [3,9,20,null ...
- LeetCode 77. 组合(回溯)
1. 题目 给定两个整数 n 和 k,返回 1 - n 中所有可能的 k 个数的组合. 示例:输入: n = 4, k = 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[ ...
- LeetCode 77 组合 -- 回溯法
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/combinations 题意: 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 ...
- Leetcode 77.组合
组合 给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合. 示例: 输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1 ...
最新文章
- 剑指offer:面试题36. 二叉搜索树与双向链表
- eclipse打开处于无响应状态解决办法
- 03.LoT.UI 前后台通用框架分解系列之——多样的表格
- TP 720N V3 8M flash 无TTL 刷回原厂教程
- BCH代币化方案讨论大爆发,你的观点是什么?
- c++修复工具_几款平价又好用的U盘修复工具分享
- (原)用pixi.js 实现 方块阵点击后原地自转效果
- Remove Duplicates from Sorted Array II leetcode java
- 利用IKVM在C#中调Java程序
- Jar 包依赖冲突排查思路和解决方法
- 如何预防销售人员带走客户?
- (转)asp.net夜话之十一:web.config详解
- java星号心形代码_肿么用JAVA打印出心形的图案
- literal和meta的意义和用法
- 破解还原卡的方法总结
- 流式传输的两大主流种类及流式传输特点
- OC Extension Color(颜色宏定义)
- 16、TFT-LCD 1.8寸显示屏使用
- 基于弹性云服务器的昇腾AI应用开发随笔【与云原生的故事】
- 【转】8核、6核、4核、双核CPU是什么意思
热门文章
- vue样式绑定与事件处理器的基本使用
- Spring Boot框架敏感信息泄露的完整介绍与SRC实战(附专属字典与PoC)
- a查询计算机主机路由表信息,计算机网络主机A向其他主机B进行通信的流程
- JSF中run项目时候Tomcat8启动不了的一种方法
- 从零打造在线版H5页面生成器
- 前端图片canvas,file,blob,DataURL等格式转换
- 响应式框架Bootstrap栅格系统
- 信息的Raid存储方式,更安全的保障,更花钱的保障!
- Guava之RangeMap
- [Swift]LeetCode281. 之字形迭代器 $ Zigzag Iterator