代码随想录算法训练营第二十四天 | 回溯算法理论基础,77. 组合 [回溯篇]

代码随想录算法训练营第二十四天

  • 回溯算法理论基础
    • 什么是回溯法
    • 回溯法的理解
    • 回溯法模板
  • LeetCode 77.组合
    • 题目描述
    • 思路
    • 参考代码
    • 总结
    • 优化版本

回溯算法理论基础

文章讲解:代码随想录#回溯算法理论基础
视频讲解:带你学透回溯算法(理论篇)| 回溯法精讲!

什么是回溯法

回溯法也叫做回溯搜索法,是一种搜索的方式。
回溯是递归的副产品,只要有递归就会有回溯。
回溯法的效率并不高,它的本质就是穷举法,有时候也会有剪枝的操作。

有些问题只有通过暴力穷举才能解决,比如可以解决以下问题:
在这里插入图片描述

回溯法的理解

回溯法解决的问题都可以抽象成一个树形结构。
回溯法解决的都是在集合中递归查找子集,集合的大小就构成了树的宽度,递归的深度就构成了树深度。
由于递归有终止条件,所以它是一棵高度有限的树。

回溯法模板

递归有三部曲,同理回溯也有三部曲。

  • 回溯函数体的返回值以及参数
    回溯算法中函数返回值一般为void。
    参数不能提前确定的,需要在根据处理逻辑来确定参数。
    所以回溯函数代码如下
void backtracking(参数)
  • 回溯函数终止条件
    一般情况下搜到叶子节点就找到了满足条件的一种解决方法,需要将这个方法保存起来,同时要结束本层递归。
if (终止条件) {存放结果;return;
}
  • 回溯搜索的遍历过程
    回溯一般都是在集合中递归搜索 ,集合的大小构成了树的宽度,递归的深度构成了树的深度。
for(选择:本层集合中元素(树中节点孩子的数量就是集合的大小)){处理节点;backtracking(路径,选择列表); // 继续递归回溯处理;
}

for循环就是遍历集合区间,可以理解一个节点有多少个孩子,这个for循环就会执行多少次。
其实,for循环就是横向遍历,递归就是纵向遍历。

回溯算法模板框架如下:

void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {处理节点;backtracking(路径,选择列表); // 递归回溯,撤销处理结果}
}

LeetCode 77.组合

题目链接:77.组合
文章讲解:代码随想录#77.组合
视频讲解:带你学透回溯算法-组合问题(对应力扣题目:77.组合)| 回溯法精讲!

题目描述

给定两个整数 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

思路

这是一道经典的回溯题,求的是组合,并非排列。
对于组合,【1,2】和【2,1】是一回事,对于排列【1,2】和【2,1】不相同。
组合是不强调元素顺序的,排列是强调元素顺序。
所以,这道题中某个元素进行过组合后,就需要不能再重复计算了。

那如何使用回溯算法呢?
上面说过回溯的问题都可以抽象成树形结构,盗图说明一下。
在这里插入图片描述
n相当于树的宽度,k相当于树的深度,每次搜索到叶子节点就表示找到了一个结果。

参考代码

typedef struct {int index;int num[100];
}Result;Result result = {0};
int **res = NULL;
int cnt = 0;void backtracking(int n, int k, int idx)
{if (result.index == k) { // 终止条件,当result中已经放入了k个元素时res[cnt] = (int*)malloc(k * sizeof(int));for(int i = 0; i < k; i++) {res[cnt][i] = result.num[i];}cnt++;return;}for (int i = idx; i <= n; i++) { // 相当于树的横向遍历result.num[result.index++] = i; // 处理节点backtracking(n, k, i + 1); // 递归遍历下一层result.index--; // 回溯result.num[result.index] = 0;}
}int** combine(int n, int k, int* returnSize, int** returnColumnSizes) {res = (int**)malloc(10000 * sizeof(int*));backtracking(n, k, 1);*returnSize = cnt;*returnColumnSizes = (int*)malloc(sizeof(int) * cnt); // 需要给returnColumnSizes分配内存for (int i = 0; i < cnt; i++) {(*returnColumnSizes)[i] = k;}return res;
}

总结

  1. 代码编译报这个错误,网上查到说明变量没有有效初始化,排查半天还是没有发现问题出在哪儿。
    在这里插入图片描述

优化版本

待补充

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

火狐国际版 - 支持安装插件

​ 【应用名称】&#xff1a;火狐国际版 - 支持安装插件 【适用平台】&#xff1a;#Android 【软件标签】&#xff1a;#Firefox 【应用版本】&#xff1a;124.0b1 (Beta) 【应用大小】&#xff1a;95MB 【软件说明】&#xff1a;FireFox无论桌面端还是移动端&#xff0c;都…

JVM工作原理与实战(三十九):G1垃圾回收器原理

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、G1垃圾回收器 1.G1垃圾回收器执行流程 二、年轻代回收 1.年轻代回收原理 2.卡表(Card Table) 3.记忆集的生成流程 4.年轻代回收的详细步骤 5.G1年轻代回收核心技术总结 三、…

前端架构: 实现脚手架终端UI样式之ANSI escape code, Chalk, Ora介绍

在脚手架当中实现命令行的UI显示 1 &#xff09;概述 在命令行中&#xff0c;如果想实现除传统的常规文本以外的内容比如想对字体进行加粗斜体下划线&#xff0c;包括对它改变颜色改变前景色改变后景色等等需要借助一个叫做 ANSI escape code 这样的一个概念它其实是一个标准&…

《图解设计模式》笔记(二)交给子类

三、Template Method模式&#xff1a;将具体处理交给子类 示例程序类图 public static void main(String[] args) {// 生成一个持有H的CharDisplay类的实例AbstractDisplay d1 new CharDisplay(H);// 生成一个持有"Hello, world."的StringDisplay类的实例AbstractD…

vue3中使用 tui-image-editor进行图片处理,并上传

效果图 下载包 pnpm i tui-image-editor pnpm i tui-color-picker调用组件 //html部分 <el-dialog v-model"imgshow" destroy-on-close width"40%" draggable align-center :show-close"true":close-on-click-modal"false">&l…

SQL注入:网鼎杯2018-unfinish

目录 使用dirmap扫描 使用dirsearch扫描 使用acunetix扫描 爆破后端过滤的字符 绕过限制获取数据 这次的进行SQL注入的靶机是&#xff1a;BUUCTF在线评测 进入到主页面后发现是可以进行登录的&#xff0c;那么我们作为一个安全人员&#xff0c;那肯定不会按照常规的方式来…

2023年12月CCF-GESP编程能力等级认证C++编程五级真题解析

一、单选题(每题 2 分,共 30 分) 第1题 下面C++代码用于求斐波那契数列,该数列第1、2项为1,以后各项均是前两项之和。下面有关说法错误的是( )。 A. fiboA( ) 用递归方式, fiboB() 循环方式 B. fiboA( ) 更加符合斐波那契数列的数学定义,直观易于理解,而 fiboB() 需…

vue中使用AraleQRCode生成二维码

vue中使用AraleQRCode生成二维码 问题背景 本文介绍vue中生成二维码的一种方案&#xff0c;使用AraleQRCode来实现。 问题分析 &#xff08;1&#xff09;安装对应的依赖包 npm i arale-qrcode --save &#xff08;2&#xff09;完整代码如下: <template><!-…

springboot访问webapp下的jsp页面

一&#xff0c;项目结构。 这是我的项目结构&#xff0c;jsp页面放在WEB-INF下的page目录下面。 二&#xff0c;file--->Project Structure,确保这两个地方都是正确的&#xff0c;确保Source Roots下面有webapp这个目录&#xff08;正常来说&#xff0c;应该本来就有&#…

基于FPGA的二维DCT变换和逆变换verilog实现,包含testbench

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 数据导入到matlab显示图像 2.算法运行软件版本 vivado2019.2 matlab2022a 3.部分核心程序 timescale 1ns / 1ps // // Company: // Engineer:…

MySql-DML-修改数据update

目录 修改数据 修改数据 update语法&#xff1a; update 表名 set 字段名1 值1 , 字段名2 值2 , .... [where 条件] ;案例1&#xff1a;将tb_emp表中id为1的员工&#xff0c;姓名name字段更新为’张三’ update tb_emp set name张三,update_timenow() where id1;案例2&…

⭐北邮复试刷题105. 从前序与中序遍历序列构造二叉树__递归分治 (力扣每日一题)

105. 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,…

web安全学习笔记【13】——信息打点(3)

信息打点-JS架构&框架识别&泄漏提取&API接口枚举&FUZZ爬虫&插件项目[1] #知识点&#xff1a; 1、业务资产-应用类型分类 2、Web单域名获取-接口查询 3、Web子域名获取-解析枚举 4、Web架构资产-平台指纹识别 ------------------------------------ 1、开源…

Apache服务

目录 引言 一、常见的http服务程序 &#xff08;一&#xff09;lls &#xff08;二&#xff09;nginx &#xff08;三&#xff09;Apache &#xff08;四&#xff09;Tomcat 二、Apache特点 三、Apache服务的安装 &#xff08;一&#xff09;yum安装及配置文件 1.配置…

c语言经典测试题2

1.题1 我们来思考一下它的结果是什么&#xff1f; 我们来分析一下&#xff1a;\\是转义为字符\&#xff0c;\123表示的是一个八进制&#xff0c;算一个字符&#xff0c;\t算一个字符&#xff0c;加上\0&#xff0c;应该有13个&#xff0c;但是strlen只计算\0前的字符个数。所以…

Android14 InputManager-InputReader的处理

IMS启动时会调用InputReader.start()方法 InputReader.cpp status_t InputReader::start() {if (mThread) {return ALREADY_EXISTS;}mThread std::make_unique<InputThread>("InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });…

注入工具SQLMAP教程:Tamper编写;指纹修改;高权限操作;目录架构等

注入工具SQLMAP教程&#xff1a;Tamper编写;指纹修改;高权限操作;目录架构 #知识点&#xff1a; 1、SQLMAP-常规猜解&字典配置 2、SQLMAP-权限操作&文件命令 3、SQLMAP-Tamper&使用&开发 4、SQLMAP-调试指纹&风险等级 #参考文章&#xff1a; https://w…

国际阿里云,想要使用怎么解决支付问题

在国内我们很多时候都需要用到国际阿里云&#xff0c;在国际阿里云需要使用就需要支付&#xff0c;自己办理visa卡比较麻烦&#xff0c;那么我们可以使用虚拟卡&#xff0c;虚拟卡办理快速简单 真实测评使用Fomepay的5347支持国际阿里云的支付&#xff0c;秒下卡&#xff0c;不…

js如何抛异常,抛自定义的异常

js如何抛异常,抛自定义的异常 最简单的自定义异常 throw "hello" 来自chrome123的控制台的测试 throw "hello" VM209:1 Uncaught hello &#xff08;匿名&#xff09; VM209:1 try{ throw "hello";}catch(e){console.log(e);} VM338:1 hello…

使用JDBC操作数据库(IDEA编译器)

目录 JDBC的本质 ​ JDBC好处 JDBC操作MySQL数据库 1.创建工程导入驱动jar包 2.编写测试代码 ​相关问题 JDBC的本质 官方(sun公司) 定义的一套操作所有关系型数据库的规则&#xff0c;即接口各个数据库厂商去实现这套接口&#xff0c;提供数据库驱动jar包我们可以使用这…