目录

  • 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. 组合 思考分析相关推荐

  1. LeetCode.77. 组合

    LeetCode.77. 组合 难度:中等 这道题属于回溯的经典题目: 回溯模板: void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择:本层集 ...

  2. leetcode 78. 子集 思考分析

    题目 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 思考分析 画出解空间树. 我们可以发现我们所需要的结果是解空间的所有结点.而我们之前 ...

  3. leetcode:77.组合

    77. 组合 来源:力扣(LeetCode) 链接: https://leetcode.cn/problems/combinations 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 ...

  4. LeetCode 77. 组合 | Python

    77. 组合 题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/combinations 题目 给定两个整数 n 和 k,返回 1 - n 中所有可能 ...

  5. Java实现 LeetCode 77 组合

    77. 组合 给定两个整数 n 和 k,返回 1 - n 中所有可能的 k 个数的组合. 示例: 输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], ...

  6. LeetCode 110. 平衡二叉树思考分析

    题目 给定一个二叉树,判断它是否是高度平衡的二叉树. 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1. 示例 1: 给定二叉树 [3,9,20,null ...

  7. LeetCode 77. 组合(回溯)

    1. 题目 给定两个整数 n 和 k,返回 1 - n 中所有可能的 k 个数的组合. 示例:输入: n = 4, k = 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[ ...

  8. LeetCode 77 组合 -- 回溯法

    来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/combinations 题意: 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 ...

  9. Leetcode 77.组合

    组合 给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合. 示例: 输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1 ...

最新文章

  1. 剑指offer:面试题36. 二叉搜索树与双向链表
  2. eclipse打开处于无响应状态解决办法
  3. 03.LoT.UI 前后台通用框架分解系列之——多样的表格
  4. TP 720N V3 8M flash 无TTL 刷回原厂教程
  5. BCH代币化方案讨论大爆发,你的观点是什么?
  6. c++修复工具_几款平价又好用的U盘修复工具分享
  7. (原)用pixi.js 实现 方块阵点击后原地自转效果
  8. Remove Duplicates from Sorted Array II leetcode java
  9. 利用IKVM在C#中调Java程序
  10. Jar 包依赖冲突排查思路和解决方法
  11. 如何预防销售人员带走客户?
  12. (转)asp.net夜话之十一:web.config详解
  13. java星号心形代码_肿么用JAVA打印出心形的图案
  14. literal和meta的意义和用法
  15. 破解还原卡的方法总结
  16. 流式传输的两大主流种类及流式传输特点
  17. OC Extension Color(颜色宏定义)
  18. 16、TFT-LCD 1.8寸显示屏使用
  19. 基于弹性云服务器的昇腾AI应用开发随笔【与云原生的故事】
  20. 【转】8核、6核、4核、双核CPU是什么意思

热门文章

  1. vue样式绑定与事件处理器的基本使用
  2. Spring Boot框架敏感信息泄露的完整介绍与SRC实战(附专属字典与PoC)
  3. a查询计算机主机路由表信息,计算机网络主机A向其他主机B进行通信的流程
  4. JSF中run项目时候Tomcat8启动不了的一种方法
  5. 从零打造在线版H5页面生成器
  6. 前端图片canvas,file,blob,DataURL等格式转换
  7. 响应式框架Bootstrap栅格系统
  8. 信息的Raid存储方式,更安全的保障,更花钱的保障!
  9. Guava之RangeMap
  10. [Swift]LeetCode281. 之字形迭代器 $ Zigzag Iterator