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

news2024/11/28 16:32:01

一、前言

今天的主题还是回溯算法,还是根据那个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.

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

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

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

相关文章

【LDLTS】拉普拉斯深能级瞬态光谱

Laplace deep level transient spectroscopy&#xff08;拉普拉斯深能级瞬态光谱&#xff0c;简称LDLTS&#xff09;是一种用于分析和表征半导体材料中深层能级缺陷的技术。它是传统能级瞬态光谱&#xff08;DLTS&#xff09;方法的扩展和改进&#xff0c;特别适用于解决传统DL…

Kubernetes kafka系列 | Strimzi 部署kafka-bridge

Strimzi kafka集群部署直通车 一、kafka bridge 介绍 Kafka Bridge 是 Apache Kafka 生态系统中的一个工具或组件&#xff0c;用于实现 Kafka 与其他系统或协议之间的通信或集成。Kafka 本身是一个分布式事件流平台&#xff0c;广泛用于构建实时数据流水线和流式应用程序。然而…

【操作系统】想要更好的学习计算机,操作系统的知识必不可少!!!

操作系统的概念 导言一、日常生活中的操作系统二、计算机系统层次结构三、操作系统的定义3.1 控制和管理计算机资源3.2 组织、调度计算机的工作与资源的分配3.3 给用户和其他软件提供方便接口与环境3.4 总结 四、操作系统的目标和功能4.1 作为管理者4.1.1 处理机管理4.1.2 存储…

用kimichat批量识别出图片版PDF文件中的文字内容

图片版的PDF文件&#xff0c;怎么才能借助AI工具来提取其中全部的文字内容呢&#xff1f; 第一步&#xff1a;将PDF文件转换成图片格式 具体方法参见文章&#xff1a;《零代码编程&#xff1a;用kimichat将图片版PDF自动批量分割成多个图片》 第二步&#xff1a;识别图片中的…

Springboot之Actuator的渗透

1. env http://ip:8080/actuator/env GET 请求 /env 会直接泄露环境变量、内网地址、配置中的用户名等信息&#xff1b;当程序员的属性名命名不规范&#xff0c;例如 password 写成 psasword、pwd 时&#xff0c;会泄露密码明文&#xff1b; 2.heapdump Heapdump地址为http…

互联网轻量级框架整合之JavaEE基础II

编写本篇代码并实际执行之前请仔细阅读前一篇互联网轻量级框架整合之JavaEE基础I Servlet 在Servlet容器中&#xff0c;Servlet是最基础的组件&#xff0c;也可以把JSP当做Servlet&#xff0c;JSP的存在意义只在于方便编写动态页面&#xff0c;使Java语言能和HTML相互结合&…

深度学习-计算机视觉入门-part1

计算机视觉入门 文章目录 计算机视觉入门一、 从卷积到卷积神经网络1.图像的基本表示2. 卷积操作3.卷积遇见深度学习3.1 通过学习寻找卷积核3.2 参数共享&#xff1a;卷积带来参数量骤减3.3 稀疏交互&#xff1a;获取更深入的特征 二、手撕卷积代码三、经典CNN模型介绍四、CNN模…

爬取BOSS直聘招聘数据(详情页数据+__zp_stoken__逆向)

这里携带逆向方法进行请求 获得数据 需要逆向方法请私聊 , 下面部分只展示爬取思路 对网页进行分析抓包 设置参数 – 城市/薪资范围/职业 对网页进行请求获得数据集 利用xpath,soup等进行进行数据清洗 将数据一csv的格式保存

【面试八股总结】超文本传输协议HTTP(一)

一、 什么是HTTP协议&#xff1f; HTTP是超文本传输协议 HyperText Transfer Protocol 特性&#xff1a; 简单、灵活、易于扩展无状态&#xff1a;服务器不会记忆HTTP状态不安全&#xff1a;通信使用明文&#xff0c;不验证通信方身份&#xff0c;无法的证明报文的完整性&…

研发设计人员能力级别定义

研发设计人员能力&级别定义 1. 源由2. 级别定义3. 级别能力3.1 助理工程师3.1.1 工作内容3.1.2 级别晋升3.1.3 详细描述 3.2 初级工程师3.2.1 工作内容3.2.2 级别晋升3.2.3 详细描述 3.3 高级工程师3.3.1 工作内容3.3.2 级别晋升3.3.3 详细描述 3.4 资深工程师3.4.1 工作内…

百度网站收录提交入口

百度网站收录提交入口 在网站刚建立或者更新内容后&#xff0c;及时将网站提交给搜索引擎是提高网站曝光和获取流量的重要步骤之一。百度作为中国最大的搜索引擎之一&#xff0c;网站在百度中的收录情况尤为重要。下面介绍一下如何通过百度的网站收录提交入口提交网站。 1. 百…

黑马HTMLCSS基础

黑马的笔记和资料都是提供好了的&#xff0c;这个文档非常适合回顾复习。我在黑马提供的笔记上做了一些微不足道的补充&#xff0c;以便自己复习查阅。该笔记比较重要的部分是 表单&#xff0c;http请求 第一章. HTML 与 CSS HTML 是什么&#xff1a;即 HyperText Markup lan…

VScode 集成终端设置默认打开当前文件夹 mac系统

一.快捷键设置 搜索 openInIntegratedTerminal 如图&#xff1a; 二.设置cmd 默认打开位置 点击设置 搜索 ntegrated:cwd 如下图&#xff1a; 三.查看ip 快捷指令&#xff1a; ipconfig getifaddr en0

【御控物联】JSON结构数据转换在物联业务中应用(场景案例二)

文章目录 一、物联网业务场景现状二、物联网业务场景数据交互格式三、JSON格式数据转换案例四、JSON数据格式转换DEMO五、在线转换工具六、技术资料 一、物联网业务场景现状 目前&#xff0c;市场上多数物联网关与物联平台捆绑售卖&#xff0c;网关采集到设备数据只能按照指定…

亲测可用,解决matplotlib中文字体乱码问题(使用Windows设置)

SimHei字体下载 https://pan.baidu.com/s/14BzhntzSeEjE4FmlVENwUw?pwd1111 用我自己的,看了好几个其他博主的帖子,所用的下载链接都失效了,太TM不靠谱了 import matplotlib.pyplot as plt import random x range(60) x_ticks_label ["11点{}分".format(i) for …

HashMap 集合源码分析

系列文章目录 文章目录 系列文章目录前言谈一谈HashMap的红黑树节点类 TreeNode 设计一、字段分析二、构造方法分析三、内部类分析四、方法分析五、扩容分析六、总结 前言 HashMap 底层是使用了 哈希表&#xff08;数组实现的哈希表&#xff09; 链表 红黑树 实现的&#xff…

Spring框架之WebFlux

Spring WebFlux高级实战 1、WebFlux作为核心响应式服务器基础 Spring 框架的整个基础设施都是围绕Servlet API 构建的&#xff0c;它们之间紧密耦合。 因此在开始深入响应式Web 之前&#xff0c;先回顾一下Web 模块的设计&#xff0c;看看它做了什么。 底层Servlet 容器负责…

mysql 数据库的MHA高可用

目录 一、MHA概述&#xff1a; 1.认识MHA&#xff1a; 2.MHA 的组成&#xff1a; 3.MHA 的特点&#xff1a; 4.MHA 工作原理&#xff1a; 5.数据流向&#xff1a; 6.数据同步方式&#xff1a; 7. mysql 的高可用 &#xff1a; 二. MySQL MHA 的搭建: 1. 修改 Master、…

LeetCode刷题:无重复字符的最长子串 详解 【3/1000 第三题】

&#x1f464;作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 作者专栏每日更新&#xff1a; LeetCode解锁1000题: 打怪升级之旅 LeetCode解锁1000题: 打怪升级之旅htt…

单片机简介(一)

51单片机 一台能够运行的计算机需要CPU做运算和控制&#xff0c;RAM做数据存储&#xff0c;ROM做程序存储&#xff0c;还有输入/输出设备&#xff08;串行口、并行输出口等&#xff09;&#xff0c;这些被分为若干块芯片&#xff0c;安装在主板&#xff08;印刷线路板&#xf…