【回溯+剪枝】组合问题!

文章目录

  • 77. 组合
  • 解题思路:回溯
  • 剪枝优化

在这里插入图片描述

77. 组合

77. 组合

​ 给定两个整数 nk,返回范围 [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

解题思路:回溯

​ 这道题直接用暴力的话会发现是超时,但是时间复杂度其实是非常高的,我们需要套 kfor 循环!所以这种组合的问题就很适合用回溯来解决,特别是当其是组合!

​ 把组合问题抽象为如下树形结构:

在这里插入图片描述

​ 接下来就是回溯三部曲:

  1. 函数头设计
    • 因为我们最后要返回一个 vector<vector<int>> ,那么期间我们也得有一个 vector<int> 来记录当前符合条件的结果
    • 除此之外,为了防止出现重复的组合,我们需要一个 cur 变量,比如这次是 [1, 2, 3] 中取 1,那么下一层递归中就要从 2 开始取,不然就会出现 11 的情况!所以需要 curindex 来记录下一层递归,搜索的起始位置。
  2. 递归函数出口
    • 通过这道题我们很清楚的知道终止条件就是要判断这个最后结果的位数也就是 k,那么我们只需要判断 v 数组中的长度是否等于 k,等于说明已经满足了,就不需要再向下递归了,则将当前的结果集放到 ret 中,然后返回即可。
  3. 函数体内容
    • 回溯法的搜索过程就是一个树型结构的遍历过程,在如下图中,可以看出 for 循环用来横向遍历,而递归的过程是纵向遍历。
      在这里插入图片描述

    • 如此我们才遍历完图中的这棵树。for 循环每次从 cur 开始遍历,然后用 path 保存取到的节点。

    • 并且不要忘记在途中递归向下取下一个数字的时候,返回之后,我们还需要继续一个回溯,也就是将 path 中刚才递归下去的那层的那个 i 去掉,这是为了防止我们取不到下下个数字,比如说 [1, 2, 3] ,我们现在取了 1,并且先继续插入到 path 中,然后我们递归到下一层取了 [1, 2],此时 2 也会被 pushpath 中,那么返回回来的时候如果不将 2 pop掉的话,path 就还是 k = 2,那么递归下一层的时候就直接返回了,就取不到 [1, 3] 了!

class Solution {vector<vector<int>> ret; // 存放结果集vector<int> path;        // 存放当前路径中的元素
public:vector<vector<int>> combine(int n, int k) {dfs(n, k, 1);return ret;}void dfs(int n, int k, int cur){// 递归函数出口if(path.size() == k){ret.push_back(path);return;}for(int i = cur; i <= n; ++i){// 处理当前节点path.push_back(i);// 递归处理当前节点后面的路径dfs(n, k, i + 1);// 回溯处理path.pop_back();}}
};

剪枝优化

​ 我们说过,回溯法虽然是暴力搜索,但也有时候可以有点剪枝优化一下的。在遍历的过程中有如下代码:

for(int i = cur; i <= n; ++i)
{path.push_back(i);dfs(n, k, i + 1);path.pop_back();
}

​ 这个遍历的范围是可以剪枝优化的,怎么优化呢?

​ 来举一个例子,n = 4k = 4 的话,那么第一层 for 循环的时候,从元素 2 开始的遍历都没有意义了。 在第二层 for 循环,从元素 3 开始的遍历都没有意义了。

​ 这么说有点抽象,如图所示:

在这里插入图片描述

因为我们要的 k4,但是从 2 开始的话,就算加上 34,最多就是 3 个数,不可能到达 k = 4 的个数,所以就是无效遍历!所以,可以剪枝的地方就在递归中每一层的 for 循环所选择的起始位置。

​ 也就是说,如果 for 循环选择的起始位置之后的元素个数 已经不足 我们需要的元素个数了,那么就没有必要搜索了。

​ 注意代码中 i,就是 for 循环里选择的起始位置。

for(int i = cur; i <= n; ++i)

接下来看一下优化过程如下:

  1. 已经选择的元素个数:path.size()
  2. 还所需的元素个数为: k - path.size()
  3. 因为 列表中剩余元素(n - i + 1)≥ 还所需的元素个数(k - path.size() 才有意义要遍历下去!
  4. 所以最后得到:i ≤ n - (k - path.size()) + 1

​ 所以优化之后的 for 循环是:

for(int i = cur; i <= n-(k-path.size())+1; ++i) // 剪枝优化

​ 优化后整体代码如下:

class Solution {vector<vector<int>> ret; // 存放结果集vector<int> path;        // 存放当前路径中的元素
public:vector<vector<int>> combine(int n, int k) {dfs(n, k, 1);return ret;}void dfs(int n, int k, int cur){// 递归函数出口if(path.size() == k){ret.push_back(path);return;}for(int i = cur; i <= n-(k-path.size())+1; ++i) // 剪枝优化{// 处理当前节点path.push_back(i);// 递归处理当前节点后面的路径dfs(n, k, i + 1);// 回溯处理path.pop_back();}}
};

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/68774.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

04树 + 堆 + 优先队列 + 图(D1_树(D7_B+树(B+)))

目录 一、基本介绍 二、重要概念 非叶节点 叶节点 三、阶数 四、基本操作 等值查询(query) 范围查询(rangeQuery) 更新(update) 插入(insert) 删除(remove) 五、知识小结 一、基本介绍 B树是一种树数据结构&#xff0c;通常用于数据库和操作系统的文件系统中。 B树…

【力扣】283.移动零

AC截图 题目 思路 遍历nums数组&#xff0c;将0删除并计数&#xff0c;最后在nums数组尾部添加足量的零 有一个问题是&#xff0c;vector数组一旦erase某个元素&#xff0c;会导致迭代器失效。好在有解决办法&#xff0c;erase会返回下一个有效元素的新迭代器。 代码 class …

Games104——引擎工具链高级概念与应用

世界编辑器 其实是一个平台&#xff08;hub&#xff09;&#xff0c;集合了所有能够制作地形世界的逻辑 editor viewport&#xff1a;可以说是游戏引擎的特殊视角&#xff0c;会有部分editor only的代码&#xff08;不小心开放就会变成外挂入口&#xff09;Editable Object&…

【力扣:新动计划,编程入门 —— 题解 ③】

—— 25.1.26 231. 2 的幂 给你一个整数 n&#xff0c;请你判断该整数是否是 2 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 如果存在一个整数 x 使得 n 2x &#xff0c;则认为 n 是 2 的幂次方。 示例 1&#xff1a; 输入&#xff1a;…

10 Flink CDC

10 Flink CDC 1. CDC是什么2. CDC 的种类3. 传统CDC与Flink CDC对比4. Flink-CDC 案例5. Flink SQL 方式的案例 1. CDC是什么 CDC 是 Change Data Capture&#xff08;变更数据获取&#xff09;的简称。核心思想是&#xff0c;监测并捕获数据库的变动&#xff08;包括数据或数…

【PyTorch】6.张量运算函数:一键开启!PyTorch 张量函数的宝藏工厂

目录 1. 常见运算函数 个人主页&#xff1a;Icomi 专栏地址&#xff1a;PyTorch入门 在深度学习蓬勃发展的当下&#xff0c;PyTorch 是不可或缺的工具。它作为强大的深度学习框架&#xff0c;为构建和训练神经网络提供了高效且灵活的平台。神经网络作为人工智能的核心技术&…

Python-基于PyQt5,wordcloud,pillow,numpy,os,sys等的智能词云生成器

前言&#xff1a;日常生活中&#xff0c;我们有时后就会遇见这样的情形&#xff1a;我们需要将给定的数据进行可视化处理&#xff0c;同时保证呈现比较良好的量化效果。这时候我们可能就会用到词云图。词云图&#xff08;Word cloud&#xff09;又称文字云&#xff0c;是一种文…

DeepSeek-R1论文研读:通过强化学习激励LLM中的推理能力

DeepSeek在朋友圈&#xff0c;媒体&#xff0c;霸屏了好长时间&#xff0c;春节期间&#xff0c;研读一下论文算是时下的回应。论文原址&#xff1a;[2501.12948] DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning 摘要&#xff1a; 我们…

【深度分析】DeepSeek大模型技术解析:从架构到应用的全面探索

深度与创新&#xff1a;AI领域的革新者 DeepSeek&#xff0c;这个由幻方量化创立的人工智能公司推出的一系列AI模型&#xff0c;不仅在技术架构上展现出了前所未有的突破&#xff0c;更在应用领域中开启了无限可能的大门。从其混合专家架构&#xff08;MoE&#xff09;到多头潜…

万物皆有联系:驼鸟和布什

布什&#xff1f;一块布十块钱吗&#xff1f;不是&#xff0c;大家都知道&#xff0c;美国有两个总统&#xff0c;叫老布什和小布什&#xff0c;因为两个布什总统&#xff08;父子俩&#xff09;&#xff0c;大家就这么叫来着&#xff0c;目的是为了好区分。 布什总统的布什&a…

Leetcode:350

1&#xff0c;题目 2&#xff0c;思路 首先判断那个短为什么呢因为我们用短的数组去挨个点名长的数组主要用map装长的数组max判断map里面有几个min数组的元素&#xff0c;list保存交集最后用数组返回list的内容 3&#xff0c;代码 import java.util.*;public class Leetcode…

Spring Boot 热部署实现指南

在开发 Spring Bot 项目时&#xff0c;热部署功能能够显著提升开发效率&#xff0c;让开发者无需频繁重启服务器就能看到代码修改后的效果。下面为大家详细介绍一种实现 Spring Boot 热部署的方法&#xff0c;同时也欢迎大家补充其他实现形式。 步骤一、开启 IDEA 自动编译功能…

LogicFlow 一款流程图编辑框架

LogicFlow是什么 LogicFlow是一款流程图编辑框架&#xff0c;提供了一系列流程图交互、编辑所必需的功能和灵活的节点自定义、插件等拓展机制。LogicFlow支持前端自定义开发各种逻辑编排场景&#xff0c;如流程图、ER图、BPMN流程等。在工作审批流配置、机器人逻辑编排、无代码…

Git进阶之旅:tag 标签 IDEA 整合 Git

第一章&#xff1a;tag 标签远程管理 git 标签 tag 管理&#xff1a; 标签有两种&#xff1a; 轻量级标签(lightweight)带有附注标签(annotated) git tag 标签名&#xff1a;创建一个标签git tag 标签名 -m 附注内容 &#xff1a;创建一个附注标签git tag -d 标签名…

riscv xv6学习笔记

文章目录 前言util实验sleeputil实验pingpongutil实验primesxv6初始化代码分析syscall实验tracesyscall实验sysinfoxv6内存学习笔记pgtbl实验Print a page tablepgtbl实验A kernel page table per processxv6 trap学习trap实验Backtracetrap实验Alarmlazy实验Lazy allocationxv…

Contrastive Imitation Learning

机器人模仿学习中对比解码的一致性采样 摘要 本文中&#xff0c;我们在机器人应用的对比模仿学习中&#xff0c;利用一致性采样来挖掘演示质量中的样本间关系。通过在排序后的演示对比解码过程中&#xff0c;引入相邻样本间的一致性机制&#xff0c;我们旨在改进用于机器人学习…

Baklib揭示内容中台与人工智能技术的创新协同效应

内容概要 在当今信息爆炸的时代&#xff0c;内容的高效生产与分发已成为各行业竞争的关键。内容中台与人工智能技术的结合&#xff0c;为企业提供了一种新颖的解决方案&#xff0c;使得内容创造的流程更加智能化和高效化。 内容中台作为信息流动的核心&#xff0c;能够集中管…

[论文阅读] (37)CCS21 DeepAID:基于深度学习的异常检测(解释)

祝大家新春快乐&#xff0c;蛇年吉祥&#xff01; 《娜璋带你读论文》系列主要是督促自己阅读优秀论文及听取学术讲座&#xff0c;并分享给大家&#xff0c;希望您喜欢。由于作者的英文水平和学术能力不高&#xff0c;需要不断提升&#xff0c;所以还请大家批评指正&#xff0…

JVM方法区

一、栈、堆、方法区的交互关系 二、方法区的理解: 尽管所有的方法区在逻辑上属于堆的一部分&#xff0c;但是一些简单的实现可能不会去进行垃圾收集或者进行压缩&#xff0c;方法区可以看作是一块独立于Java堆的内存空间。 方法区(Method Area)与Java堆一样&#xff0c;是各个…

火语言RPA--文本内容提取

&#x1f6a9;【组件功能】&#xff1a;通过前后截取、通配符参数组合或纯正则方式提取源字符串中指定的文本内容 配置预览 配置说明 源内容 支持T或# 默认FLOW输入项 进行处理、匹配的对象&#xff0c;若为空&#xff0c;以上一个组件的输出为源内容。 提取方式 前后截取…