代码随想录第27天 | 39. 组合总和、40.组合总和II、131.分割回文串

一、前言

今天的主题还是回溯算法,还是根据那个backtracking模板,但是今天会涉及到去重和一些小细节的问题。

二、组合总和

1、思路:

我一开始的想法就是在for循环转化为:

for(int i = 0; i < size; i++)

但是这个是会陷入一个死循环,一直会在0的这个位置进行累加,所以必须使用start作为一个 

一个i的初始变量,这样才能实现不同数字且相同的累加。

再有一个关键的因素终止条件:

if (sum > target){
    return;
}

这个如果没有,那就一直循环递归去了。

2、整体代码如下:

class Solution {
private:
    vector<int> path;
    vector<vector<int>> result;
    void backtracking(vector<int> &candidates, int target, int sum, int start) {
        if (sum > target) {
            return;
        }
        if (sum == target) {
            result.push_back(path);
            return;
        }
        for (int i = start; i < candidates.size(); i++) {
            sum += candidates[i];
            path.push_back(candidates[i]);
            backtracking(candidates, target, sum ,i);
            sum -= candidates[i];
            path.pop_back();
        }
    }
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        result.clear();
        path.clear();
        backtracking(candidates, target, 0, 0);
        return result;
    }
};

剪枝操作,for循环的修正:

for (int i = start; i < candidates.size() && sum + candidates[i] <= target; i++)

 整体代码:

class Solution {
private:
    vector<int> path;
    vector<vector<int>> result;
    void backtracking(vector<int> &candidates, int target, int sum, int start) {
        if (sum > target) {
            return;
        }
        if (sum == target) {
            result.push_back(path);
            return;
        }
        for (int i = start; i < candidates.size() && sum + candidates[i] <= target; i++) {
            sum += candidates[i];
            path.push_back(candidates[i]);
            backtracking(candidates, target, sum ,i);
            sum -= candidates[i];
            path.pop_back();
        }
    }
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        result.clear();
        path.clear();
        sort(candidates.begin(), candidates.end()); // 需要排序
        backtracking(candidates, target, 0, 0);
        return result;
    }
};

 

三、组合总和|||

1、思路:

我的最开始的思路并没有包括到去重的思想

导致出现了多个重复的答案,

思路图是这样的:

首先就得有一个used数组,全部设置为false然后在递归回溯过程中,涉及到了两个新的名词:树尾和树层。树层是递归的每一层,树尾就是树的深度,在这个题目当中,我们所需要去重的是数层,当前一个和后一个相同时,used为false说明没有被使用,就可以去掉这个重复的元素了,而在深度遍历中,就没有这种情况,后面为ture就说明在深度当中,就可以往下遍历了。

这里也有一个小小的剪枝操作:

(sum + candidates[i]) <= target

 2、整体代码如下:

class Solution {
private:
    vector<int> path;
    vector<vector<int>> result;
    void backtracking(vector<int>& candidates, int target, int sum, int startIndex, vector<bool>& used) {
        if (sum == target) {
            result.push_back(path);
            return;
        }
        for (int i = startIndex; i < candidates.size() && (sum + candidates[i]) <= target; i++) {
            // 去重
            if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) {
                continue;
            }
            path.push_back(candidates[i]);
            sum += candidates[i];
            used[i] = true;
            backtracking(candidates, target, sum, i + 1, used);
            // 回溯
            used[i] = false;
            path.pop_back();
            sum -= candidates[i];
        }
    }
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        // 创建一个判定数组
        vector<bool> used(candidates.size(), false);
        // 需要先排序
        sort(candidates.begin(), candidates.end());
        backtracking(candidates, target, 0, 0, used);
        return result;
    }
};

 四、分割回文串

1、思路:

这个题目还是比较抽象的,首先来看一下这个分割的图例:

这是不断往下递归,分割,回溯,递归,分割的过程。直到size == startIndex才是停止,所以终止条件就是:

if (s.size() == startIndex)

就说明可以终止了,内部执行的语句就是:

{
    result.push_back();
    return;
}

 这里的小小的疑惑就是为什么一到最后就可以直接添加了,而不需要判断是否为回文串。

这里的判断逻辑主要是在for循环中去体现的。

(1)返回值和参数为:

void backtracking(tring &s, int startIndex)

这里的startIndex就是作为切割线来使用的;

(2)终止条件刚刚说了到了,这里就不提了,然后就是进入for循环了,这里就需要加上一个判断是否为回文串的判断条件,如果是,那么就把子串添加到path中 ,这里是判断回文串函数:

    // 判断回文串函数
    bool isPalindrome(const string &s, int satrt, int end) {
        for (int i = satrt, j = end; i < j; i++, j--) {
            if (s[i] != s[j]) {
                return false;
            }
        }
        return true;
    }

 (3)for循环里面的组成如下

 

        // 大循环
        for (int i = startIndex; i < s.size(); i++) {
            // 判断是否为回文串
            if (isPalindrome(s, startIndex, i)) {
                path.push_back(s.substr(startIndex, i - startIndex + 1));
            } else {
                // 不是就继续在该树继续往下分割。
                continue;
            }
            // 递归
            backtracking(s, i + 1);
            // 回溯
            path.pop_back();
        }

 现在一行分割下去,到了低,就return,然后就是从序号1开始搜索,依次进行。

1、整体代码如下:

class Solution {
private:
    vector<string> path;
    vector<vector<string>> result;
    // startIndex就是切割线
    void backtracking(string s, int startIndex) {
        // 终止条件
        if (startIndex == s.size()) {
            result.push_back(path);
            return;
        }
        // 大循环
        for (int i = startIndex; i < s.size(); i++) {
            // 判断是否为回文串
            if (isPalindrome(s, startIndex, i)) {
                path.push_back(s.substr(startIndex, i - startIndex + 1));
            } else {
                // 不是就继续在该树继续往下分割。
                continue;
            }
            // 递归
            backtracking(s, i + 1);
            // 回溯
            path.pop_back();
        }

    }

    // 判断回文串函数
    bool isPalindrome(const 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;
    }
public:
    vector<vector<string>> partition(string s) {
        backtracking(s, 0);
        return result;
    }
};

今日学习时间:2小时;

leave message:

The lights and shades, whose well-accorded strife gives all the strength and color of our life.

在我们的生活中,一切的力量和色彩,都来自苦乐的光影,以及适度的斗争。 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C#实现Word文档转Markdown格式(Doc、Docx、RTF、XML、WPS等)

文档格式的多样性丰富了我们的信息交流手段&#xff0c;其中Word文档因其强大的功能性而广受欢迎。然而&#xff0c;在网络分享、版本控制、代码阅读及编写等方面&#xff0c;Markdown因其简洁、易于阅读和编辑的特性而展现出独特的优势。将Word文档转换为Markdown格式&#xf…

智慧安防监控EasyCVR视频调阅和设备录像回看无法自动播放的原因排查与解决

智慧安防监控EasyCVR视频管理平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入与汇聚管理。国标GB28181协议视频监控/视频汇聚EasyCVR平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、…

JMeter自定义日志与日志分析

1 JMeter日志概览 JMeter与Java程序一样&#xff0c;会记录事件日志&#xff0c;日志文件保存在bin目录中&#xff0c;名称为jmeter.log。当然&#xff0c;我们也可以在面板中直接察看日志&#xff0c;点击右上角黄色标志物可以打开日志面板&#xff0c;再次点击收起。 可见&…

数据分析之Tebleau可视化:折线图、饼图、环形图

1.折线图的绘制 方法一&#xff1a; 拖入订单日期和销售金额&#xff0c;自动生成一个折线图 方法二&#xff1a; 选中订单日期和销售金额&#xff08;摁住ctrl可以选择多个纬度&#xff09; 点击右边的智能推荐&#xff0c;选择折线图 2.双线图的绘制、双轴的设置 方法一&…

在Python中使用PyPDF2库在PDF文件中插入内容

目录 一、引言 二、PyPDF2库的安装 三、PyPDF2库的基本使用 四、在PDF文件中插入内容 五、注意事项和扩展 六、总结 一、引言 PDF&#xff08;Portable Document Format&#xff09;文件因其跨平台、不易被篡改的特性&#xff0c;广泛应用于日常办公和文档交流中。在实际…

MySQL连接查询补充与三表连查

前言 MySQL多表联查是指在一个查询语句中同时查询多个表&#xff0c;并根据表之间的关联条件进行数据的匹配和筛选。通过多表联查&#xff0c;我们可以获取到更丰富的数据信息&#xff0c;从而满足复杂的查询需求。先前了解了三种简单的连接查询方式&#xff0c;这里将进一步介…

17.应用负载压力测试

早些点&#xff0c;下午题考&#xff0c;最近几年出现的少&#xff1b; 备考较为简单&#xff1b;历年真题相似度高&#xff1b; 主要议题&#xff1a; 1.负载压力测试概述 注意这些测试细微的差别&#xff1b; 负载测试和压力测试的方法比较相似&#xff0c;但是目的不同&a…

如何使用potplayer在公网环境访问内网群晖NAS中储存在webdav中的影视资源

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-D7WJh3JaNVrLcj2b {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

臻奶惠无人售货机:新零售时代的便捷消费革命

臻奶惠无人售货机&#xff1a;新零售时代的便捷消费革命 在新零售的浪潮中&#xff0c;智能无人售货机作为一个创新的消费模式&#xff0c;已经成为距离消费者最近的便捷购物点之一。这种模式不仅能够满足居民对消费升级的需求&#xff0c;还能通过建立多样化和多层次的消费体…

2024年04月编程语言流行度排名

点击查看最新编程语言流行度排名&#xff08;每月更新&#xff09; 2024年04月编程语言流行度排名 编程语言流行度排名是通过分析在谷歌上搜索语言教程的频率而创建的 一门语言教程被搜索的次数越多&#xff0c;大家就会认为该语言越受欢迎。这是一个领先指标。原始数据来自…

MotionBuilder 脚本执行

目录 MediaPipe_Pose_in_MotionBuilder 你可以用以下几种方式执行你的脚本&#xff1a; MediaPipe_Pose_in_MotionBuilder https://github.com/Ndgt/MediaPipe_Pose_in_MotionBuilder/blob/main/PoseLandmark.py tcp通信 https://github.com/nils-soderman/motionbuilder-s…

银行业架构网络BIAN (Banking IndustryArchitecture Network)详细介绍

BIAN ( The Banking Industry Architecture Network) 是一个业界多方协作的非营利性组织&#xff0c;由全球领先银行、技术提供商、顾问和学者组成&#xff0c;定义了一个用以简化和标准化核心银行体系结构的银行技术框架。这一框架基于面向服务的架构 (SOA) 原则&#xff0c;银…

RabbitMQ安装及Springboot 集成RabbitMQ实现消息过期发送到死信队列

死信队列 RabbitMQ 的死信队列&#xff08;Dead-Letter-Exchanges&#xff0c;简称 DLX&#xff09;是一个强大的特性&#xff0c;它允许在消息在队列中无法被正常消费&#xff08;例如&#xff0c;消息被拒绝并且没有设置重新入队&#xff0c;或者消息过期&#xff09;时&…

微服务管理(完整)

前言&#xff1a; 分享一篇学微服务管理的过程 一&#xff0c;etcd入门 1&#xff0c;简介 1.1&#xff0c;etcd是什么 etcd是CoreOS团队于2013年6月发起的开源项目&#xff0c;它的目标是构建一个高可用的分布式键值(key-value)数据库。 官网上的一段描述&#xff1a; A…

Mac 怎么提高音频播放速度?

mac 怎么提高音频播放速度&#xff1f;在Mac上&#xff0c;有时我们可能需要加快音频文件的播放速度&#xff0c;比如加快听力材料的播放速度以提高效率&#xff0c;或者快速浏览录音文件等。幸运的是&#xff0c;Mac系统自带的音频播放器iTunes和QuickTime都提供了简单的方法来…

中科驭数DPU技术开放日秀“肌肉”:云原生网络、RDMA、安全加速、低延时网络等方案组团亮相

2024年3月29日&#xff0c;中科驭数以“DPU构建高性能云算力底座”为主题的线上技术开放日活动成功举办。在开放日上&#xff0c;中科驭数集中展现了其在低时延网络、云原生网络及智算中心网络三大关键场景下的技术成果与五大核心DPU解决方案&#xff0c;凸显了中科驭数在高性能…

HUAWEI 华为交换机 配置 Eth-Trunk 接口流量本地优先转发示例(堆叠)

组网需求 说明 S5720I-10X-PWH-SI-AC 和 S5720I-6X-PWH-SI-AC 不支持此配置。 如 图 3-23 所示&#xff0c;为了增加设备的容量采用设备堆叠技术&#xff0c;将 Switch3 和 Switch4通过专用的堆叠电缆链接起来&#xff0c;对外呈现为一台逻辑交换机。为了实现设备间的备份、…

C# WPF编程-Application类(生命周期、程序集资源、本地化)

C# WPF编程-Application类 应用程序的生命周期创建Application对象应用程序的关闭方式应用程序事件 Application类的任务显示初始界面处理命令行参数访问当前Application对象在窗口之间进行交互 程序集资源添加资源检索资源pack URI内容文件 本地化构建能够本地化的用户界面 每…

vue改名为威优易?

文章目录 vue改名为威优易&#xff1f; 祝大家愚人节快乐哇&#xff01; 哈哈&#xff0c;大家愚人节快乐&#xff01;看来我刚刚的“爆料”确实把大家吓了一跳&#xff0c;Vue.js要改名为“威优易”&#xff1f;这纯粹是官方在这个愚人节使者开的一个小小玩笑啦&#xff01; …

R语言技能 | 不同数据类型的转换

原文链接&#xff1a;R语言技能 | 不同数据类型的转换 本期教程 写在前面 今天是4月份的第一天&#xff0c;再过2天后再一次迎来清明小假期。木鸡大家是否正常放假呢&#xff1f; 我们在使用R语言做数据分析时&#xff0c;会一直对数据进行不同类型的转换&#xff0c;有时候…