给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。

示例 1:
输入:n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]

示例 2:
输入:n = 1, k = 1
输出:[[1]]

提示:

1 <= n <= 20
1 <= k <= n

这道题是典型的回溯题目,回溯算法虽然效率不怎么高但是在一些情况下只能用回溯去解决,就比如这道题目,如果暴力解法的话是做不出来的,回溯算法一般都是在集合中递归找子集,为了更方便去理解,回溯算法解决的问题可以理解为一个N叉树问题,就以这道题目为例子,我们来看看如何解决;

首先确定回溯函数backtracking到底该怎么写,
返回值先假设为void,传入参数k和n肯定是要有的,这里还额外需要一个start来记录本层递归的中,集合从哪里开始遍历;

怎么理解呢,这道题如果转化为一个N叉树的话,那么k就是树的最大深度,n就是这个树的宽度,所以我们需要一个循环来遍历n,即对宽度的遍历,循环中套递归,对每一个宽度进行递归,所以递归其实实现的是深度的遍历;

回溯函数其实就是一个递归函数,所以终止条件该是什么?
如果一个树通过dfs的方式遍历,一旦到了叶子节点就可以结束了,所以这里也一样,一旦递归深度达到了k(即最大深度),就可以结束了;

代码如下:

class Solution {public:vector<vector<int>> ans;vector<int> path;void backtracking(int n, int k, int start) {if (path.size() == k) {ans.push_back(path);return ;}for (int i = start; i <= n; ++i) {path.push_back(i);backtracking(n, k, i + 1); //递归深度,i + 1代表下一层宽度起点要从下一个开始path.pop_back();//回溯来撤销处理的节点(画图就好理解了)}}vector<vector<int>> combine(int n, int k) {backtracking(n, k, 1);return ans;}
};

这个代码同样可以通过剪枝优化一下,只需要改一下宽度遍历中的n,
优化需要以下几步:
已经选择的元素个数:path.size();
还需要的元素个数为: k - path.size();
在集合n中至多要从该起始位置 : n - (k - path.size()) + 1开始遍历
这里加1是为了包括了起始位置
最后优化后其实只需要改动对宽度的循环这一栏就可以了,即

for (int i = start; i <= n - (k - path.size()) + 1; ++i)

代码如下:

class Solution {public:vector<vector<int>> ans;vector<int> path;void backtracking(int n, int k, int start) {if (path.size() == k) {ans.push_back(path);return ;}for (int i = start; i <= n - (k - path.size()) + 1; ++i) {path.push_back(i);backtracking(n, k, i + 1);path.pop_back();}}vector<vector<int>> combine(int n, int k) {backtracking(n, k, 1);return ans;}
};

77. 组合(回溯算法)相关推荐

  1. 137. Leetcode 77. 组合 (回溯算法-组合问题)

    class Solution:def combine(self, n: int, k: int) -> List[List[int]]:res = []def backtrack(n, k, s ...

  2. LeetCode 77 组合 -- 回溯法

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

  3. 77.组合 回溯 队列 剪枝 python

    思路 来源 https://leetcode-cn.com/problems/combinations/solution/hui-su-suan-fa-jian-zhi-python-dai-ma-j ...

  4. No.77 组合:回溯法

    结果 执行用时 :636 ms, 在所有 cpp 提交中击败了15.29%的用户 内存消耗 :167.7 MB, 在所有 cpp 提交中击败了8.43%的用户 时间消耗和空间消耗有点高,不过在使用回溯 ...

  5. 【代码随想录】二刷-回溯算法

    回溯算法 <代码随想录> 什么是回溯算法? 回溯算法也可以叫做回溯搜索法,它是一种搜索方式. 回溯是递归的副产品,只要有递归就会有回溯. 回溯法的效率: 回溯法的本质是穷举,穷举所有可能, ...

  6. 一篇带你搞透回溯算法

    回溯算法应用场合 回溯算法和递归算法一般同时出现,一般递归算法的下面就是回溯的逻辑. 一般说递归函数,其实就是回溯函数.回溯一般不会单独出现. 回溯法其实是一个纯暴力的搜索算法.有些问题用for循环搜 ...

  7. Suzy找到实习了吗 Day24 | 回溯算法开始啦:回溯的理论知识,77组合(有一个问题没有解决)

    回溯算法理论 回溯算法解决的问题 组合问题 切割问题 子集问题 排列问题 棋盘问题 算法模板 函数没有返回值 业界给回溯算法命名:backtracking 算法伪代码模板 def backtracki ...

  8. 2021.1.9每日复习 75.颜色分类(复习快速排序)+ 77.组合(回溯算法)

    ***75.颜色分类(复习快速排序) class Solution {public void sortColors(int[] nums) {//方法一:冒泡排序// int n = nums.len ...

  9. 求n个数中第k大的数_互联网高频面试题目:「回溯算法」求组合总和

    我将算法学习相关的资料已经整理到了Github :https://github.com/youngyangyang04/leetcode-master,里面还有leetcode刷题攻略.各个类型经典题 ...

最新文章

  1. Dalvik线程模型
  2. [Java基础]JDK内置注解
  3. 理解物体检测中的Objectness
  4. 002 Ajax中传输格式为HTML
  5. java https请求 证书_java发https请求,证书配置
  6. 为什么计算机连接u盘不显示内存不足,U盘明明有空间却提醒空间不足怎么解决...
  7. 大米云主机首批优秀体验师新鲜出炉——软件服务篇
  8. Mac苹果电脑怎么调整磁盘区域的大小
  9. PHP爬虫常用技术:v8js(执行js代码)
  10. yolo系列外文翻译_yolov3论文中英对照版
  11. iphone4s蜂窝数据连不上解决方案
  12. wll多功能超小linux,WLL多功能PXE网启服务器3.6终结版
  13. 计算机硬件数据统计实验报告,实验二数据统计01
  14. 几种 Proximity Graphs 的单调性分析
  15. Python正则(粗略)
  16. 达科为在创业板递交注册申请:拟募资8亿元,吴庆军父女为实控人
  17. 懒癌治疗仪 - 写在前面
  18. MFC 屏蔽ESC键和ENTER键关闭对话框的方法
  19. 我的数字IC学习路线
  20. JSP标签隐藏以及不可修改

热门文章

  1. php 发送微信请求失败的原因,微信小程序模拟正常 真机服务器请求出错
  2. 混合云数据中心运维的管理
  3. 机房安防系统常见故障原因及处理方法
  4. DL之AlexNet:利用卷积神经网络类AlexNet实现猫狗分类识别(图片数据增强→保存h5模型)
  5. AI:2020年6月22日北京智源大会演讲分享之09:00-09:50 全体大会《AI精度与隐私的博弈》
  6. ML之XGBoost:XGBoost参数调优的优秀外文翻译—《XGBoost中的参数调优完整指南(带python中的代码)》(四)
  7. CV之NS之VGG16:基于TF Slim(VGG16)利用七个不同的预训练模型实现快速NS风格
  8. 功能测试话题分享-0323
  9. 数据库基础之一--DDL(数据库定义语言),DCL(数据库控制语言)
  10. 44.更多replace案例