LeetCode 热题 100 | 回溯(二)

目录

1  39. 组合总和

2  22. 括号生成

3  79. 单词搜索


菜鸟做题,语言是 C++,感冒快好版

关于对回溯算法的理解请参照我的上一篇博客;

在之后的博客中,我将只分析回溯算法中的 for 循环。

1  39. 组合总和

题眼:candidates 中的同一个数字可以无限制重复被选取。

根据题眼,for 循环结构如下:

for (int i = begin; i < candidates.size(); ++i) {output.push_back(candidates[i]);sum += candidates[i];helper(candidates, target, output, i, sum);sum -= candidates[i];output.pop_back();
}

与之前题解的唯一不同之处在于:递归时传的不再是 begin + 1,而是 i 。这是由于每个字母都可以被重复使用,因此我们可以从当前字母开始选择,而非跳过它。

思路说明图:

假设 target = 8 。在第一层函数中,i = begin = 0,即从 2 开始选择,再将 i 传给第二层函数;在第二层函数中,i = begin = 0,即从 2 开始选择,再将 i 传给第三层函数;以此类推。直到第五层函数,此时 sum = 2 + 2 + 2 + 2 > 8,即继续加下去也永远无法得到 target 。因此,返回到第四层函数,i += 1,即考虑 3 是否可行。以此类推。

由上述分析可得,递归终止条件为:

if (sum > target) return;
if (sum == target) {ans.push_back(output);return;
}

一是,当前 sum 已经大于 target,不能再增加下去了;二是,当前 sum 已经等于 target,也不能再增加下去了(区别在于,我们要将成功的组合记录下来)。

class Solution {
public:vector<vector<int>> ans;void helper(vector<int> & candidates, int target,vector<int> & output, int begin, int sum) {if (sum > target) return;if (sum == target) {ans.push_back(output);return;}for (int i = begin; i < candidates.size(); ++i) {output.push_back(candidates[i]);sum += candidates[i];helper(candidates, target, output, i, sum);sum -= candidates[i];output.pop_back();}}vector<vector<int>> combinationSum(vector<int>& candidates, int target) {vector<int> output;helper(candidates, target, output, 0, 0);return ans;}
};

你可能会认为传递的参数太多,那你可以把它们都定义成全局变量。

2  22. 括号生成

for 循环结构如下:

output.push_back('(');
++l;
helper(output, n, l, r);
output.pop_back();
--l;
output.push_back(')');
++r;
helper(output, n, l, r);
output.pop_back();
--r;

这种写法和  78. 子集  很像。在  78. 子集  中,只有两种选择,即是否让当前字母进入子集;同样地,在本题中也只有两种选择,即当前坑位填左括号还是右括号(我们还设置了变量来记录当前左右括号的个数)。

递归终止条件为:

if (l > n || r > n || r > l) return;
if (l == n && r == n) {ans.push_back(output);return;
}

一是,如果当前左或右括号的个数大于所需的个数,则返回;二是,如果当前右括号的个数大于当前左括号的个数,则返回,这是因为该右括号肯定找不到配对的左括号;三是,如果左右括号的个数都等于所需的个数了,则记录成功的组合并返回。

class Solution {
public:vector<string> ans;void helper(string & output, int n, int l, int r) {if (l > n || r > n || r > l) return;if (l == n && r == n) {ans.push_back(output);return;}output.push_back('(');++l;helper(output, n, l, r);output.pop_back();--l;output.push_back(')');++r;helper(output, n, l, r);output.pop_back();--r;}vector<string> generateParenthesis(int n) {string output;helper(output, n, 0, 0);return ans;}
};

3  79. 单词搜索

非典型 for 循环结构如下:

visited[r][c] = 1;bool up = false, down = false, left = false, right = false;
if (r - 1 >= 0 && !visited[r - 1][c]) left = helper(board, word, r - 1, c, i + 1);
if (r + 1 < nr && !visited[r + 1][c]) right = helper(board, word, r + 1, c, i + 1);
if (c - 1 >= 0 && !visited[r][c - 1]) up = helper(board, word, r, c - 1, i + 1);
if (c + 1 < nc && !visited[r][c + 1]) down = helper(board, word, r, c + 1, i + 1);visited[r][c] = 0;return up || down || left || right;

这里的 “选择” 就是 “从当前位置出发,有四个方向可以走”。本来想写个 for 循环来遍历四个方向的,无奈这里有返回值,因此无法一概而论。这里的结构还是满足 “处理-递归-清除” 的格式,只是最后多了一个返回值。只要有一个方向能走得通,我们都返回 true 。

它不像之前的题一样,每个坑位/位置管好自己即可,而是要和后面的坑位/位置共荣辱。

递归终止条件:

if (board[r][c] != word[i]) return false;
if (i == word.size() - 1) return true;

一是,当前字母与 word 中的字母不同,返回 false;二是,已经找到了所有字母,返回 true 。

这道题感觉像是图论和回溯的杂合体啊啊啊。之前的题都是只有一个方向(右),而这道题有四个方向(上下左右)。

class Solution {
public:int nr, nc;vector<vector<int>> visited;bool helper(vector<vector<char>> & board, string word, int r, int c, int i) {if (board[r][c] != word[i]) return false;if (i == word.size() - 1) return true;visited[r][c] = 1;bool up = false, down = false, left = false, right = false;if (r - 1 >= 0 && !visited[r - 1][c])left = helper(board, word, r - 1, c, i + 1);if (r + 1 < nr && !visited[r + 1][c])right = helper(board, word, r + 1, c, i + 1);if (c - 1 >= 0 && !visited[r][c - 1])up = helper(board, word, r, c - 1, i + 1);if (c + 1 < nc && !visited[r][c + 1])down = helper(board, word, r, c + 1, i + 1);visited[r][c] = 0;return up || down || left || right;}bool exist(vector<vector<char>>& board, string word) {nr = board.size();nc = board[0].size();visited.resize(nr);for (auto & v : visited)v.resize(nc);for (int i = 0; i < nr; ++i) {for (int j = 0; j < nc; ++j) {if (helper(board, word, i, j, 0)) return true;}}return false;}
};

说明:我们认为每个位置都有可能是 word 的起始点,因此使用双重 for 循环进行遍历。不过,只有当找完了 word 时才返回 true;反之,会走向最后的 false 。代码如下:

for (int i = 0; i < nr; ++i) {for (int j = 0; j < nc; ++j) {if (helper(board, word, i, j, 0)) return true;}
}return false;

最好取 row 和 column 的首字母来定义变量,否则把自己都绕晕了。

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

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

相关文章

15届蓝桥杯第二期模拟赛题单详细解析

文章目录 &#x1f9e1;&#x1f9e1;t1_求余&#x1f9e1;&#x1f9e1;思路代码 &#x1f9e1;&#x1f9e1;t2_灌水&#x1f9e1;&#x1f9e1;思路代码 &#x1f9e1;&#x1f9e1;t3_字符显示&#x1f9e1;&#x1f9e1;思路代码 &#x1f9e1;&#x1f9e1;t4_区间最大和…

网络计算机

TCP/IP四层模型 应用层&#xff1a;位于传输层之上&#xff0c;主要提供两个设备上的应用程序之间信息交换的服务&#xff0c;它定义了信息交换的格式&#xff0c;消息会交给下一层传输层来传递。我们把应用层交互的数据单元称为报文。应用层工作在操作系统的用户态&#xff0…

YOLOv8_pose-Openvino和ONNXRuntime推理【CPU】

纯检测系列&#xff1a; YOLOv5-Openvino和ONNXRuntime推理【CPU】 YOLOv6-Openvino和ONNXRuntime推理【CPU】 YOLOv8-Openvino和ONNXRuntime推理【CPU】 YOLOv7-Openvino和ONNXRuntime推理【CPU】 YOLOv9-Openvino和ONNXRuntime推理【CPU】 跟踪系列&#xff1a; YOLOv5/6/7-O…

Android 音频系统

导入 早期Linux版本采用的是OSS框架&#xff0c;它也是Unix及类Unix系统中广泛使用的一种音频体系。 ALSA是Linux社区为了取代OSS而提出的一种框架&#xff0c;是一个源代码完全开放的系统(遵循GNU GPL和GNU LGPL)。ALSA在Kernel 2.5版本中被正式引入后&#xff0c;OSS就逐步…

C语言:操作符详解(下)

目录 一、逗号表达式二、下标访问[ ]、函数调用()1. [ ]下标引用操作符2.函数调用操作符 三、结构成员访问操作符1.结构体(1) 结构的声明(2) 结构体变量的定义和初始化 2.结构成员访问操作符(1)结构体成员的直接访问(2)结构体成员的间接访问 四、操作符的属性&#xff1a;优先级…

Rudolf and the Ball Game

传送门 题意 思路 暴力枚举每一个妆台的转换条件 code #include<iostream> #include<cstdio> #include<stack> #include<vector> #include<algorithm> #include<cmath> #include<queue> #include<cstring> #include<ma…

【Docker】容器的生态系统

Docker提供了一整套技术支持&#xff0c;包括核心技术、平台技术、支持技术。 核心技术 容器核心技术是指能让Container&#xff08;容器&#xff09;在host&#xff08;集群、主机&#xff09;上运行起来的那些技术。 1&#xff09;容器规范&#xff1a;OCI&#xff08;runt…

搭建mysql主从复制(主主复制)

1&#xff1a;设主库允许远程连接(注意&#xff1a;设置账号密码必须使用的插件是mysql_native_password&#xff0c;其他的会连接失败) #切换到mysql这个数据库&#xff0c;修改user表中的host&#xff0c;使其可以实现远程连接 mysql>use mysql; mysql>update user se…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的零售柜商品检测软件(Python+PySide6界面+训练代码)

摘要&#xff1a;开发高效的零售柜商品识别系统对于智能零售领域的进步至关重要。本文深入介绍了如何运用深度学习技术开发此类系统&#xff0c;并分享了全套实现代码。系统采用了领先的YOLOv8算法&#xff0c;并与YOLOv7、YOLOv6、YOLOv5进行了性能比较&#xff0c;呈现了诸如…

蓝桥杯每日一题:血色先锋队

今天浅浅复习巩固一下bfs 答案&#xff1a; #include<iostream> #include<algorithm> #include<cstring>using namespace std; typedef pair<int,int> PII;const int N510; int n,m,a,b; int dist[N][N]; PII q[N*N]; int hh0,tt-1;int dx[]{1,0,-1,…

网络层:地址解析协议ARP、网际控制报文协议ICMP、虚拟专用网络VPN、网络地址转换NAT

文章目录 地址解析协议ARP解决的问题ARP解析流程ARP高速缓存 网际控制报文协议ICMPICMP报文的种类ICMP差错报告报文ICMP询问报文 ICMP应用举例分组网间探测PING(Packet InterNet Groper)traceroute(tracert)确定路径的MTU 虚拟专用网络专用地址虚拟专用网络远程接入VPN(remote …

某鱼弹幕逆向

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018…

mysql题库详解

1、如何创建和删除数据库&#xff1f; 创建数据库 CREATE DATABASE 数据库名; 删除数据库 drop database 数据库名; 2、MyISAM与InnoDB的区别&#xff1f; 1&#xff09;事务&#xff1a;MyISAM 不支持事务 InnoDB 支持 2&#xff09;行锁/表锁&#xff1a;MyISAM 支持表级锁…

Redis中AOF数据持久化

AOF介绍 AOF&#xff08;Append Only File&#xff09;持久化&#xff1a;以独立日志的方式存储了 Redis 服务器的顺序指令序列&#xff0c;并只记录对内存进行修改的指令。 当Redis服务发生雪崩等故障时&#xff0c;可以重启服务并重新执行AOF文件中的指令达到恢复数据的目的…

SpringMVC | SpringMVC中的 “数据绑定”

目录: “数据绑定” 介绍1.简单数据绑定 :绑定 “默认数据” 类型绑定 “简单数据类型” 类型 &#xff08;绑定Java“基本数据类型”&#xff09;绑定 “POJO类型”绑定 “包装 POJO”“自定义数据” 绑定 :Converter (自定义转换器) 2.复杂数据绑定 :绑定数组绑定集合 作者简…

ubuntu 18.04安装教程(详细有效)

文章目录 一、下载ubuntu 18.04镜像二、安装ubuntu1. 点击下载好的Vmware Workstation&#xff0c;点击新建虚拟机&#xff0c;选择 “自定义(高级)”&#xff0c;之后下一步。2. 默认配置&#xff0c;不需要更改&#xff0c;点击下一步。3. 选择 “安装程序光盘映像文件(iso)(…

Windows 11 DirectX 诊断工具获取电脑型号

Windows 11 DirectX 诊断工具获取电脑型号 1. dxdiag2. DirectX 诊断工具References 1. dxdiag Win R 打开运行窗口&#xff0c;输入 dxdiag&#xff0c;点击确定按钮。 2. DirectX 诊断工具 通过 DirectX 诊断工具&#xff0c;可以直接找到电脑型号&#xff0c;型号是硬件制…

RocketMQ学习笔记三(黑马)大神级

课程来源:6.RocketMQ安装_哔哩哔哩_bilibili (时长:19.5h) 讲解版本:4.5版本(我是以4.8版本实践的) 目录 第一部分 核心功能 第1章 RocketMQ的下载、安装、启动和测试(Linux环境) 启动: 测试: 第2章 RocketMQ集群搭建 2.1 集群特点 2.2 集群模式 2.3 双主…

程序员必备开发工具、程序员必备集成开发环境(IDE)

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

Java项目:52 springboot基于SpringBoot的旅游网站的设计与实现013

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 旅游网站主要功能如下&#xff1a; 1.用户管理&#xff1a;注册、登录、退出、修改密码&#xff1b; 2.分类显示&#xff1a;显示旅游路线的…