C国演义 [第三章]

这篇具有很好参考价值的文章主要介绍了C国演义 [第三章]。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

组合

力扣链接
给定两个整数 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

分析

暴力解法当然是用 for循环 :
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;
    }
}

n = 100, k = 3时:

int n = 100;
for (int i = 1; i <= n; i++) {
    for (int j = i + 1; j <= n; j++) {
        for (int u = j + 1; u <= n; n++) {
            cout << i << " " << j << " " << u << endl;
        }
    }
}

如果 k = 50呢? 就要用50个for循环. 有一个问题; 我们如何控制 50 个for循环呢

为了解决这种情况: 我们采用 回溯

回溯也是一种暴力, 但是可以用递归次数来解决for循环的层数
🗨️它是如何解决for循环的层数呢?

  • 递归里面套用for循环 — — 每一次递归套用一个for循环, 那么我们解决递归的层数来控制for循环的层数

过程是非常抽象的, 但是递归的过程可以用 二叉树来做一个形象的理解
C国演义 [第三章]
先看一个分支(纵向):
集合是 [1, 2, 3, 4], 从中任选一个 , 以取 1 为例子
然后集合是 [2, 3, 4], 从中任选一个就已经达到目标了, [1, 2], [1, 3], [1, 4]

集合是[1, 2, 3, 4], 从中任选一个, 以取 2 为例子
然后集合是 [3, 4], 从中任选一个就已经达到目标了, [2, 3], [2, 4]

集合是[1, 2, 3, 4], 从中任选一个, 以取 3为例子
然后集合是[ 4 ], 从中任选一个就已经达到目标了, [3, 4]

集合是[1, 2, 3, 4], 从中任选一个, 以取 4为例子
然后集合是[ ], 就不能继续递归下去了

🗨️为啥集合是 [1, 2, 3, 4], 取 2, 然后剩余集合是 [3, 4]. 为啥不是[1. 3. 4 ]?

  • 因为求的是 组合, 所以不用注意相同数值的顺序
    如果剩余集合是 [1, 3, 4], 那么叶子结点就是 [2, 1], [2, 3], [2, 4]
    这个时候, [1, 2] 和 [2, 1] 是重复的
    所以我们需要一个变量来控制下一层递归的开头

每次从集合中选取元素, 下一层递归的范围随着选取元素而缩减

步骤

递归函数的返回值和参数

一般回溯的返回值都是 void, 除非有特殊要求
需要定义两个全局变量, 一个来记录单层结果, 一个来记录全部结果

vector<int> path; // 记录单层结果
vector<int<vector<int>> result; // 记录全部结果

虽然这两个变量也可以放在参数列表里面, 但是这会导致参数列表过于冗杂, 而看不清回溯的逻辑

数组大小n 和 结果大小k 肯定是在参数列表中的

为了避免结果有重复的, 需要有一个变量来控制每一层递归的区间集合(开头), 我们一般用 startindex

⇒ 所以我们的递归函数应该如下:

vector<int> path;
vector<vector<int>> result;
void backtracking(int n, int k, int startindex )

递归结束的条件

path是用来记录单层结果的, 根据题目要求,
递归结束的条件是: path的大小是2
那么我们就把path收入result里面, 并不继续向下递归

    if(path.size()) == k)
    {
        result.push_back(path);
        return;
    }

单层逻辑

单层逻辑肯定是一个for循环
for循环的起始点是 startindex, 终止点是 n

    for(int i = startindex; i <= n; i++ )
    {
    
	}

我们先把沿途的数值收入path

    for(int i = startindex; i <= n; i++ )
    {
    	path.push_back(i);
	}

继续向下递归, 此时的起始点就变成 i + 1

    for(int i = startindex; i <= n; i++ )
    {
    	path.push_back(i);
    	backtracking(n, k, i + 1);
	}

回溯, 让一棵树的情况更加完整

    for(int i = startindex; i <= n; i++ ) // 控制横向遍历
    {
    	path.push_back(i); // 处理节点
    	backtracking(n, k, i + 1); // 纵向递归
    	path.pop_back(); // 回溯, 撤销处理的节点
	}```

##  代码

```cpp
class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;
    
    void backtracking(int n, int k, int startindex)
    {
        // 终止条件
        if(path.size() == k)
        {
            result.push_back(path);
            return ;
        }
        
        // 单层逻辑
        for(int i = startindex; i <= n; 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 result;
    }
};

C国演义 [第三章]

组合总和 III

力扣链接

找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:
只使用数字1到9
每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

示例 1:
输入: k = 3, n = 7
输出: [[1,2,4]]
解释:
1 + 2 + 4 = 7
没有其他符合的组合了
示例 2:
输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
解释:
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
没有其他符合的组合了。
示例 3:
输入: k = 4, n = 1
输出: []
解释: 不存在有效的组合。
在[1,9]范围内使用4个不同的数字,我们可以得到的最小和是1+2+3+4 = 10,因为10 > 1,没有有效的组合。

  • 提示:
    2 <= k <= 9
    1 <= n <= 60
class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;
    
    void backtracking(int n, int k, int startindex, int sum)
    {
        if(path.size() == k && sum == n)
        {
            result.push_back(path);
            return ;
        }
        
        for(int i = startindex; i <= 9; i++)
        {
            path.push_back(i);
            sum += i;
            backtracking(n, k, i + 1, sum);
            sum -= i;
            path.pop_back();
        }
    }
    vector<vector<int>> combinationSum3(int k, int n) 
    {
        backtracking(n, k, 1, 0);
        return result;
        
    }
};

C国演义 [第三章]文章来源地址https://www.toymoban.com/news/detail-485907.html

到了这里,关于C国演义 [第三章]的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【计组】第三章练习

    【计组】第三章练习

    4、设有一个具有20位地址和32位字长的存储器,问: (1)该存储器能存储多少个字节的信息? 220 × 32 bits = 1M × 4B = 4MB (220是2的20次方,上标打不出来…) (2)如果存储器由512K * 8位SRAM芯片组成,需要多少片? (1024K * 32)/(512K * 8) = 8 片 (3)需要多少位地址做芯片选择? 存

    2024年02月04日
    浏览(21)
  • 第三章-上网行为安全

    第三章-上网行为安全

    1)宽带滥用 2)上网难监管 3)信息泄露 4)网络违法 5)安全威胁 1)上网行为三要素:用户、流量、行为 2)功能需求 (AC的功能)-- 重点 用户认证 应用控制 网页过滤 行为审计 流量管理 应用选路 互联网上网行为管控 一体化网关 无线Wi-Fi管控营销 无线防共享上网 全网上

    2024年01月23日
    浏览(14)
  • 第三章:函数

    1.定义 设 x , y 是两个变量,x的变化范围是实数集D,如果对于任何的x∈D,按照一定的法则都有唯一确定的y值与之对应。则称变量y是变量x的函数。记为 y = f(x) 。称D为函数的 定义域 ,x为自变量,y为因变量。全体函数值的集合称为函数y的 值域 。 2.函数的表示方法 1. 公式

    2024年02月01日
    浏览(14)
  • 第三章 Elasticsearch简介

    第三章 Elasticsearch简介

    Elasticsearch (后称为 ES )是一个天生支持分布式的搜索、聚合分析和存储引擎。 搜索引擎 全文检索引擎 分布式文档系统 分布式数据库 OLAP系统 分布式搜索中间件 不要去死背概念,概念应该作为一种辅助的手段帮助我们去理解一项技术或知识,总之,等你真正会用了,你就

    2024年02月06日
    浏览(15)
  • Linux第三章

    Linux第三章

    无论是Windows、MacOS、Linux均采用多用户的管理模式进行权限管理。在Linux系统中,拥有最大权限的账户名为:root(超级管理员) root用户拥有最大的系统操作权限,而普通用户在许多地方的权限是受限的(普通用户的权限,一般在其HOME目录内是不受限的,一旦出了HOME目录,大

    2023年04月26日
    浏览(17)
  • C++[第三章]--程序结构

    class里面的函数实现可以放到class外面实现,class里面声明即可。所以这部代码可以放到.h文件中如: 在cpp里面实现这些函数即可如: 多个cpp文件出现同名函数(非类里面的函数)会混淆。 定义:.h/.cpp文件中: 调用者源文件中: 直接使用: a::fun, a::fun2 using声明: using a::fun; // 以后

    2024年02月15日
    浏览(10)
  • 408数据结构第三章

    特性后进先出 只允许在 一端 进行插入或删除操作的线性表 每接触一种新的数据结构类型,都应该分别从逻辑结构、存储结构和对数据的运算三方面入手 操作 initstack(s)初始化一个空栈s stackempty(s)判断一个栈是否为空 push(s,x)进栈,未满成为新栈顶 pop(s,x)出栈,非空弹出栈顶元

    2024年02月09日
    浏览(15)
  • 第三章微服务配置中心

    第三章微服务配置中心

    Nacos配置管理 Nacos除了可以做注册中心,同样可以做配置管理来使用。 当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。我们需要一种统一配置管理方案,可以集中管理所有实例的配置。 Nacos一方面可以将配置集中管理

    2024年02月10日
    浏览(7)
  • 第三章 处理机调度

    第三章 处理机调度

    目录 一、调度的概念、层次 2.1 调度的基本概念 2.2 调度的三个层次 2.2.1 高级调度 2.2.2 低级调度 2.2.3 中级调度 2.2.3.1 进程的挂起态 2.2.4 三层调度的联系、对比 二、进程调度的时机、切换与过程、方式 2.1 进程调度的时机 2.2 进程调度的方式 2.2.1 非抢占方式 2.2.2 抢占方式

    2024年02月10日
    浏览(14)
  • 线性代数---第三章向量

    线性代数---第三章向量

    2024年02月12日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包