补录:day023-回溯法

40.组合II

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用 一次 。

注意:解集不能包含重复的组合。

思路:组合题目二,这个题目与组合一的区别在于,本题目中的candidates的每个元素只能使用一次,而且本题中的candidate数组中会有重复的元素。要对此进行去重

首先定义三个成员变量,一维和二维的数组和sum,sum代表累加的和。在回溯函数中如果当前的sum和等于目标值,将结果放到二维数组中并返回。然后继续往下看,通过for循环遍历目标数组(此时在for的循环条件里加入了剪枝的操作,当 当前的和加上当前对应的数组值小于等于目标值,才可以继续进入循环,否则的话就不进入循环,因为不满足条件进入循环也没必要了),如果i大于0(不能是第一层),并且当前对应的数组的值不能等于前一个值,如果相等,在遍历这第二个相同的值就没有意义了,因为前一个值所遍历的范围已经包含第二个值了,所以应该将第二个去重掉,(在这道题目中我定义了一个存储布尔类型的动态数组,并且它的大小与candidate的大小相同,来记录已经遍历过的元素,如果元素已经使用过,就设置为TRUE),在if条件中判断如果当前值与前一个相等并且前一个的used数组显示为FALSE。为什么一定是等于FALSE呢,等于TRUE不可以吗?如果等于TRUE的话,我们可能会遗漏一些正确的组合,如下图所示:

而我们实际要剪枝的是:也就是Carl哥说的树层和树枝去重(下图是树层,上图是树枝)

去重的条件大概就是这些,然后呢就是正常的回溯递归,注意还有一点的是我们依然采用了startIndex来更新递归后的搜索初始节点进行去重。

class Solution {
public:
vector<int> path;
vector<vector<int>> res;
int sum;void travelBacking(vector<int>& candidates, int target,int startIndex,vector<bool>& used){if(sum==target){res.push_back(path);return ;}for(int i=startIndex;i<candidates.size()&&sum+candidates[i]<=target;i++){if(i>0&&used[i-1]==false&&candidates[i]==candidates[i-1]){continue;}sum+=candidates[i];path.push_back(candidates[i]);used[i]=true;travelBacking(candidates,target,i+1,used);//每个数字在每个组合中只能使用一次used[i]=false;sum-=candidates[i];path.pop_back();}}
public:vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {int startIndex=0;vector<bool> used(candidates.size(),false);sort(candidates.begin(),candidates.end());travelBacking(candidates,target,startIndex,used);return res;}
};

131.分割回文串

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 
回文串。
返回 s 所有可能的分割方案。

 思路:分割字符串第一眼看似很难,但实际上与前面的组合题目很像的,需要增加的操作就是要定义一个判断回文串的函数,然后正常定义回溯函数,如果传入的startIndex要大于等于字符串长度,startIndex代表切割线,如果切割线等于字符串长度,代表切割到尾部了,将path存入result并返回,这是回溯三部曲的第二步,确认回溯终止条件,第一步是传入参数,第三步是确认单层递归逻辑,首先判断当前子串是否为回文串,如果是回文串进入循环,将其截取出来并存入字符串str中,注意截取时传入的参数是startIndex--字符串的起始位置和长度--i-startIndex+1,因为长度就是下标加1,如果非回文串的话,continue(continue 语句用于跳过当前循环的剩余部分,并立即开始下一次循环迭代);注意,有人可能不理解为什么开始值和结束值是startIndex和i呢? startIndex是起始位置,而i则是结束位置。

class Solution {
public:
vector<string> path;
vector<vector<string>> result;bool isPartition(string s,int start,int end){//判断是否为回文串for(int i=start,j=end;i<j;i++,j--){if(s[i]!=s[j]){return false;}}return true;}void travelBacking(string s,int startIndex){if(startIndex>=s.size()){result.push_back(path);return;}for(int i=startIndex;i<s.size();i++){if(isPartition(s,startIndex,i)){string str=s.substr(startIndex,i-startIndex+1);path.push_back(str);}else{continue;}travelBacking(s,i+1);path.pop_back();}}vector<vector<string>> partition(string s) {travelBacking(s, 0);return result;}
};

78.子集

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的
子集
(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

 思路:此题相对于上面的题目来说算是简单的了,同样的回溯模版,差别在于在它是取所有的集合,要在回溯函数开始时将path加入到二维数组中,然后正常将该题目抽象成树形结构遍历。如图所示:(选自代码随想录图解)

class Solution {
public:
vector<int> path;
vector<vector<int>> res;void travelBacking(vector<int>& nums,int startIndex){res.push_back(path);if(startIndex>=nums.size()){return;}for(int i=startIndex;i<nums.size();i++){path.push_back(nums[i]);travelBacking(nums,i+1); path.pop_back();}}
public:vector<vector<int>> subsets(vector<int>& nums) {travelBacking(nums,0);return res;}
};

90.子集II

给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的 
子集
(幂集)。

解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。

 思路: 和上一道题很像,主要就是和组合二大体思路的去重,树层去重和树枝去重,通过一个used数组来记录是否使用过这个数字,当当前的值与前一个值相等时,并且前一个值为FALSE,代表是树层去重,无需遍历当前的树枝了,因为前面的树枝遍历已经包含了这个的树枝遍历,还需要注意的一点是,因为子集是找出所以的组合并记录,所以要在回溯函数开头将一维数组存到二维数组中。

class Solution {
public:
vector<int> path;
vector<vector<int>> res;void travelBacking(vector<int>& nums,int startIndex,vector<bool>& used){res.push_back(path);if(startIndex>=nums.size()){return;}for(int i=startIndex;i<nums.size();i++){if(i>0&&nums[i]==nums[i-1]&&used[i-1]==false){continue;}path.push_back(nums[i]);used[i]=true;travelBacking(nums,i+1,used);used[i]=false;path.pop_back();}}
public:vector<vector<int>> subsetsWithDup(vector<int>& nums) {vector<bool> used(nums.size(),false);sort(nums.begin(),nums.end());travelBacking(nums,0,used);return res;}
};

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

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

相关文章

2024世界机器人大会将于8月21日至25日在京举行

2024年的世界机器人大会预定于8月21日至25日&#xff0c;在北京经济技术开发区的北人亦创国际会展中心隆重举办。 本届大会以“共育新质生产力 共享智能新未来”为核心主题&#xff0c;将汇聚来自全球超过300位的机器人行业专家、国际组织代表、杰出科学家以及企业家&#xff0…

【云原生】Prometheus Pushgateway使用详解

目录 一、前言 二、Pushgateway概述 2.1 什么是Pushgateway 2.1.1 Pushgateway在Prometheus中的位置 2.2 为什么需要Pushgateway 2.3 Pushgateway作用 2.4 Pushgateway 工作原理 2.5 Pushgateway 使用场景 2.6 Pushgateway 优缺点 三、Pushgateway 部署 3.1 二进制安…

ip透传及实例

IP 透传介绍 “IP 透传”&#xff08;IP Passthrough&#xff09;是一种网络配置方式&#xff0c;指的是将网络服务提供商分配给用户的公网 IP 地址直接传递或分配给用户设备&#xff0c;而不是经过网络地址转换&#xff08;NAT&#xff09;处理。 在传统的网络环境中&#xf…

HTML5+JavaScript绘制彩虹和云朵

HTML5JavaScript绘制彩虹和云朵 彩虹&#xff0c;简称虹&#xff0c;是气象中的一种光学现象&#xff0c;当太阳光照射到半空中的水滴&#xff0c;光线被折射及反射&#xff0c;在天空上形成拱形的七彩光谱&#xff0c;由外圈至内圈呈红、橙、黄、绿、蓝、靛、紫七种颜色。事实…

Qt WebEngine基于WebEngineScript注入js脚本

在之前的文章中&#xff0c;我们介绍了Qt WebEngine注入js的用法&#xff0c;及runJavaScript()的用法&#xff0c;该方法主要是用在页面加载完成后&#xff0c;为了和网页做一些交互时使用。有时候需要监听网页加载完成的一些状态或信息&#xff0c;则需要网页加载前注入js来实…

VSCODE platformio ESP32-S3 内置 JTAG 接口断点单步调试笔记

ESP32 S3的两种JTAG调试方法 ESP32 S3的有两种JTAG调试方法&#xff0c;直接连接板子上的JTAG引脚进行调试&#xff0c;或者用ESP32-S3 内置 JTAG 接口进行调试&#xff0c;这些方法有助于开发者在开发过程中进行更深入的调试。 1、ESP32-S3 内置 JTAG 接口 使用 ESP32-S3 内…

VSCode Markdown Preview Enhanced启用PlantumlL支持

目录 VSCode Markdown Preview Enhanced启用Plantuml支持安装Java下载Plantuml最新版本jar文件配置Markdown Preview Enhanced中Plantuml Jar Path路径 VSCode Markdown Preview Enhanced启用Plantuml支持 当需要Markdown支持PlantUML语法显示支持时&#xff0c;需要进行如下设…

学单片机怎么在3-5个月内找到工作?

每个初学者&#xff0c;都如履薄冰&#xff0c;10几年前&#xff0c;我自学单片机时&#xff0c;也一样。 想通过学习&#xff0c;找一份体面点的工作&#xff0c;又害怕辛辛苦苦学出来&#xff0c;找不到工作。 好在&#xff0c;当初执行力&#xff0c;还算可以&#xff0c;自…

使用FFmpeg实现摄像头RTMP实时推流

在当今的数字时代,视频直播已成为连接人与人之间的重要桥梁,广泛应用于在线教育、远程会议、娱乐直播等多个领域。随着技术的不断进步,人们对于直播的实时性、稳定性和高质量需求日益增加。为了实现高效的视频直播,选择合适的工具和协议至关重要。 RTMP(Real-Time Messagi…

LVS集群中的负载均衡技术

目录 一、LVS技术原理 二、NAT模式原理及部署方法 1、工作原理 2、部署方法 1、网络配置 2、软件安装与启用 3、测试 三、DR模式原理及部署方法 1、工作原理 2、部署方法 1、网络配置 2、解决vip响应问题 3、测试 四、ipvsadm命令及参数 1、管理集群服务&#x…

MySQL增删改查(基础)

1、. 新增&#xff08;Create&#xff09; 语法&#xff1a; INSERT [INTO] table_name[(column [, column] ...)] VALUES (value_list) [, (value_list)] ... 例子&#xff1a; -- 创建一张学生表 DROP TABLE IF EXISTS student; CREATE TABLE student (id INT,sn INT com…

DC-DC控制器芯片内部如何实现PWM控制?

大家好,这里是大话硬件。 在前面文章中,结合UC3842芯片内部框图,陆续实现了芯片的振荡器功能,参考电压功能,过欠压保护功能。今天这篇文章对PWM控制功能进行仿真。 根据框图,器件内部主要是误差放大器和高速比较器。 实现思路如下:模拟一个输出电压,纹波变化频率和…

较新版本Cesium使用本地源码编译打包

0 写作背景 较新版本的Cesium&#xff08;1.100版本及以后&#xff09;在代码结构上做了一定的调整&#xff0c;打包方式也随之发生了一些变化。 Starting with version 1.100, CesiumJS will be published alongside two smaller packages cesium/engine and cesium/widgets …

stm32—GPIO

0. 引入 在单片机产品中,我们常常可以见到三种模块:LCD灯、KEY按键、BEEP蜂鸣器 LED灯: 一个比较常见的LED电路LED0 ---------- 通过控制LED0引脚(电线) 给它一个低电平(低电压),LED灯就会亮 给它一个高电平(高电压),LED灯就会灭 …

【数据结构】—— 栈

一、栈的基本概念1、栈的定义2、栈的常见基本操作 二、栈的顺序存储1、栈的顺序存储结构2、顺序栈存储实现&#xff08;1&#xff09;初始化&#xff08;2&#xff09;判空&#xff08;3&#xff09;进栈&#xff08;4&#xff09;出栈&#xff08;5&#xff09;取栈顶元素&…

使用 CSS 打印样式为 Web 页面设置专业的打印机效果

对于有打印需求的网页&#xff0c;特别是文章的详情页&#xff0c;需要设置专门的打印样式来适配页面。CSS 打印样式允许你为网页设置专门用于打印的样式。文本就是专门介绍如何使用 CSS 打印样式为 Web 页面设置专业的打印机效果。 media print 通过使用 media print 媒体查…

算法打卡 Day19(二叉树)-平衡二叉树 + 二叉树的所有路径 + 左叶子之和 + 完全二叉树的节点个数

Leetcode 101-平衡二叉树 文章目录 Leetcode 101-平衡二叉树题目描述解题思路 Leetcode 257-二叉树的所有路径题目描述解题思路 Leetcode 404-左叶子之和题目描述解题思路 Leetcode 222-完全二叉树的节点个数题目描述解题思路 题目描述 https://leetcode.cn/problems/balanced…

Chainlit快速实现AI对话应用将聊天数据的持久化到postgres关系数据库中

概述 默认情况下&#xff0c;Chainlit 应用不会保留其生成的聊天和元素。即网页一刷新&#xff0c;所有的聊天记录&#xff0c;页面上的所有聊天记录都会消失。但是&#xff0c;存储和利用这些数据的能力可能是您的项目或组织的重要组成部分。 之前写过一篇文章《Chainlit快速…

实现高亮的全文分页检索

文章目录 &#x1f31e; Sun Frame&#xff1a;SpringBoot 的轻量级开发框架&#xff08;个人开源项目推荐&#xff09;&#x1f31f; 亮点功能&#x1f4e6; spring cloud模块概览常用工具 &#x1f517; 更多信息1.sun-club-infra 模块SubjectEsServiceImpl.java1.querySubje…

大数据-74 Kafka 高级特性 稳定性 - 控制器、可靠性 副本复制、失效副本、副本滞后 多图一篇详解

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…