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 的首字母来定义变量,否则把自己都绕晕了。
相关文章:
LeetCode 热题 100 | 回溯(二)
目录 1 39. 组合总和 2 22. 括号生成 3 79. 单词搜索 菜鸟做题,语言是 C,感冒快好版 关于对回溯算法的理解请参照我的上一篇博客; 在之后的博客中,我将只分析回溯算法中的 for 循环。 1 39. 组合总和 题眼:c…...
混合内容错误https中加载了http
一、遇到问题 iframe嵌套时,混合内容错误https中加载了http,但是已经确认了ifreme中是https的,最后发现在/my/edit?applyid1改为/my/edit/?applyid1,加了一个斜杠,直接解决了 /my/edit是vue页面,其他页…...
游戏免费下载平台模板源码
功能介绍 此游戏网站模板源码是专门为游戏下载站而设计的,旨在为网站开发者提供一个高效、易于维护和扩展的解决方案。 特点: 响应式设计:我们的模板可以自适应不同设备屏幕大小,从而为不同平台的用户提供最佳的浏览体验。 …...
鸿蒙视频播放的实现
文章目录 前言播放效果视频播放的实现总结 一、前言 现在市面上很多应用都跟视频有关,那么在鸿蒙系统上怎么来播放视频呢,今天就讲解视频播放控件,让你也能快速地进行视频播放功能开发。 最后呢,我会提供一个鸿蒙中涉及的主要…...
QT----计算器
目录 1 搭建标准界面2、 逻辑编写2.1 初始化 github链接:基于qt的计算器 更多内容可以点击这里查看个人博客:个人博客 1 搭建标准界面 按照下图搭设界面 修改样式让这计算器看起来更像一点,同时对按钮分组进行样式编辑,添加字符…...
Linux:kubernetes(k8s)Deployment的操作(13)
创建deployment 命令 kubectl create deploy nginx-deploy --imagenginx:1.7.9 再去使用以下命令分别查询 ubectl get deploy kubectl get replicaset kubectl get pod 他是一个层层嵌套的一个关系 首先是创建了一个 deploy 里面包含着replicaset replicaset里面含有…...
20240619-James-快速鸟瞰并发编程, 呕心沥血整理的架构技术(第3篇)
接着第1, 2篇后,我们继续来跟进一下并发编程的其它内容,如下: 第9节 java.util.concurrent包 线程池 线程池的核心接口是ExecutorService。java.util.concurrent还提供了一个静态工厂类Executors,其中包含用于创建配置线程池的…...
C语言——详解字符函数和字符串函数(一)
Hi,铁子们好呀!今天博主来给大家更一篇C语言的字符函数和字符串函数~ 具体讲的内容如下: 文章目录 🎆1.字符分类函数💯💯⏩1.1 什么是字符分类函数的?💯💯⏩1.2 字符函数的类型有哪…...
三款内衣洗衣机的顶级较量:希亦、小吉、由利,谁才是性价比之王?
洗衣机在我们的生活中可谓是非常常见的了,几乎每家每户都具备着一台。即便是有洗衣机,也有不少人不会将自己我贴身衣物直接扔在洗衣机里清洗,而是会自己手工手洗。这跟我们传统上的观念有很大的关系,认为把内衣、内裤等贴身衣物放…...
Java枚举多值映射应用
在日常系统交互中,经常遇到两个系统间定义的枚举不一致,在接口调用时需要转换,记录实现,方便备查。 场景 双方的支付方式定义不同,一侧为数字,一侧为英文,若使用 if 判断,则显得繁琐…...
css--浮动
一. 浮动的简介 在最初,浮动是用来实现文字环绕图片效果的,现在浮动是主流的页面布局方式之一。 二. 元素浮动后的特点 🤢脱离文档流。😊不管浮动前是什么元素,浮动后:默认宽与高都是被内容撑开࿰…...
基于有限状态机开发健壮的Nodejs/TCP客户端
有限状态机是一种数学计算模型,它描述了在任何给定时间只能处于一种状态的系统的行为。形式上,有限状态机有五个部分: 初始状态值 (initial state)有限的一组状态 (states)有限的一组事件 (events)由事件驱动的一组状态转移关系 (transition…...
javaEE13(网站第8章两个课后题)
1、对“jspservletjavabean实现分页查询”功能做如下补充: (1)记录批量删除:每个记录前添加复选框,点击批量删除,删除选中记录。 增加跳转到任意页功能。用户可改变每页记录条数。 页面&am…...
【Leetcode每日一题】 递归 - 反转链表(难度⭐)(35)
1. 题目解析 题目链接:206. 反转链表 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 一、递归函数的核心任务 递归函数的主要职责是接受一个链表的头指针,并返回该链表逆序后的新头结点。递归…...
Unity基础学习
目录 基础知识点3D数学——基础Mathf三角函数坐标系 3D数学——向量向量模长和单位向量向量的加减乘除向量点乘向量叉乘向量插值运算 3D数学——四元数为何使用四元数四元数是什么四元数常用方法四元数计算 MonoBehavior中的重要内容延迟函数协同程序协同程序原理 Resources资源…...
Java并发编程学习笔记:AQS
Java并发编程学习笔记:AQS 一、底层原理核心功能同步状态管理CLH 队列和线程调度机制独占模式与共享模式模板方法设计模式自旋、阻塞与超时机制 运行流程 二、锁的公平性公平锁非公平锁 三、容器实现 JUC中的AQS(AbstractQueuedSynchronizer)…...
Github上哪些好用的工具
专注于web漏洞挖掘、内网渗透、免杀和代码审计,感谢各位师傅的关注!网安之路漫长,与君共勉! Qexo-爱写博客的师傅强烈推荐 漂亮的 Hexo 静态博客编辑器。该项目是基于 Django 的 Hexo 静态博客管理后台,支持文章管理、…...
如何确保面试流程标准化操作,避免人为因素影响**
一、背景 在招聘过程中,面试作为关键环节,其标准化操作至关重要。标准化不仅有助于提高面试效率和质量,还能减少人为因素的影响,确保公平、公正和客观。本文将从以下八个方面探讨如何确保面试流程的标准化操作。 二、明确面试标准 制定明确的面试标准和要求,确保所有面试…...
YOLOv7改进 | 更换主干网络之PP-LCNet
前言:Hello大家好,我是小哥谈。PP-LCNet是一个由百度团队针对Intel-CPU端加速而设计的轻量高性能网络。它是一种基于MKLDNN加速策略的轻量级卷积神经网络,适用于多任务,并具有提高模型准确率的方法。与之前预测速度相近的模型相比,PP-LCNet具有更高的准确性。此外,对于计…...
MySQL基础-----多表查询之子查询
目录 前言 子查询概述 1.概念 2.分类 一、标量子查询 二、列子查询 三、行子查询 四、表子查询 前言 上一期我们讲了内外连接查询以及自连接查询,那么本期我们就学习多表查询的子查询。本期会详细讲解什么是子查询,以及子查询的相关功能…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
