131. 分割回文串(力扣LeetCode)

文章目录

  • 131. 分割回文串
    • 题目描述
    • 回溯代码

131. 分割回文串

题目描述

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

回文串 是正着读和反着读都一样的字符串。

示例 1:

输入:s = “aab”
输出:[[“a”,“a”,“b”],[“aa”,“b”]]

示例 2:

输入:s = “a”
输出:[[“a”]]

提示:

  • 1 <= s.length <= 16
  • s 仅由小写英文字母组成

回溯代码

在此代码片段中,子字符串是通过递归函数 backtracking 来获取的。函数 backtracking 是一个回溯算法的实现,用于找到字符串 s 的所有可能的回文分割。回文分割是指将字符串分割成若干子串,使得每个子串都是回文的。

下面是 backtracking 函数在寻找子串时的详细过程:

  1. 函数 backtracking 接收原始字符串 s 和一个 startIndex 参数,该参数指示当前考虑的子串的起始位置。

  2. 在每一层递归中,函数通过循环从 startIndex 遍历到字符串 s 的末尾。

  3. 在每次迭代中,它通过调用 isPalindrome 函数来检查当前考虑的子串 s[startIndex, i] 是否是回文。

  4. 如果检测到子串是回文,使用 substr 方法从 s 中提取出回文子串。substr 方法的第一个参数是子串的起始位置,第二个参数是要提取的字符数。这里,提取的字符数计算为 i - startIndex + 1,表示从 startIndex 到 i(包含 i)的子串长度。

  5. 获取到的回文子串 str 被加入到临时路径 path 中。

  6. 然后,递归调用 backtracking 函数,在寻找剩余子串的新的回文分割方案,此时 startIndex 更新为 i + 1,因为 i 位置的字符已经包含在了当前找到的回文子串内。

  7. 递归返回后,执行 path.pop_back(),这是回溯的一部分,它将最后一个添加到 path 中的回文子串移除,以便 path 可以用于下一次循环迭代时的新的分割方案。

  8. 当 startIndex 大于或等于字符串 s 的长度时,意味着已经到达字符串的末尾,当前 path 中存储的回文子串序列即为 s 的一个有效分割,此时将 path 加入到 result 中。

通过这种方法,代码实现了在递归循环中对字符串进行子串的分割,并确保了每个分割方案中的所有子串都是回文的。

假设我们有一个字符串 s = “aab” 并且我们想要找到所有可能的回文分割方案。下面是 backtracking 函数在这个字符串上操作的示例:

  1. 初始调用 backtracking("aab", 0)startIndex 是 0,意味着我们从字符串的第一个字符开始。

  2. 第一层递归的循环从 i = 0 开始:

    a. 检查子串 s[0, 0]"a" 是否是回文 — 是,所以 path 变为 ["a"]

    b. 递归调用 backtracking("aab", 1) 查看从第二个字符开始的所有回文分割方案。

  3. 第二层递归开始,现在考虑的子串是 "ab"

    a. 循环从 i = 1 开始,检查子串 s[1, 1]"a" 是否是回文 — 是,所以现在 path 变为 ["a", "a"]

    b. 递归调用 backtracking("aab", 2) 查看从第三个字符开始的所有回文分割方案。

  4. 第三层递归开始,现在考虑的子串是 "b"

    a. 循环从 i = 2 开始,检查子串 s[2, 2]"b" 是否是回文 — 是,所以现在 path 变为 ["a", "a", "b"]

    b. 递归调用 backtracking("aab", 3),发现 startIndex 等于字符串长度,意味着找到了完整的一组分割方案。将其添加到 result 中,result = [["a", "a", "b"]]

    c. 回溯发生,path.pop_back() 移除最后一个元素 "b",现在 path = ["a", "a"]

  5. 返回到第二层递归,继续 i 的循环,现在 i = 2

    a. 检查子串 s[1, 2]"ab" 是否是回文 — 不是,所以不改变 path

    b. 循环结束,开始回溯,path.pop_back() 移除最后一个元素 "a",现在 path = ["a"]

  6. 返回到第一层递归,继续 i 的循环,下一次 i = 1

    a. 检查子串 s[0, 1]"aa" 是否是回文 — 是,所以 path 变为 ["aa"]

    b. 递归调用 backtracking("aab", 2) 查看从第三个字符开始的所有回文分割方案。

  7. 第四层递归开始,现在考虑的子串是 "b"

    a. 循环从 i = 2 开始,检查子串 s[2, 2]"b" 是否是回文 — 是,所以 path 变为 ["aa", "b"]

    b. 递归调用 backtracking("aab", 3),发现 startIndex 等于字符串长度,意味着找到了另外一个完整的一组分割方案。将其添加到 result 中,现在 result = [["a", "a", "b"], ["aa", "b"]]

  8. 回溯发生,path.pop_back() 移除 "b",回到 path = ["aa"]。然后第四层递归的循环结束,path.pop_back() 再次移除 "aa",回到 path = []

最终的 result 包含了所有可能的回文分割方案:[["a", "a", "b"], ["aa", "b"]]。这样,我们就逐步构建了每一个可能的回文分割方案并将有效的方案添加到结果集中。

在这里插入图片描述

class Solution {
public:
    // 主函数,调用回溯函数并返回结果
    vector<vector<string>> partition(string s) {
        backstracking(s,0); // 从字符串的第一个字符开始进行回溯
        return result; // 返回所有可能的分割方案
    }

private:
    vector<vector<string>> result; // 存储所有可能的分割方案
    vector<string> path; // 用于存储当前的分割方案

    // 检查一个子串是否是回文串
    bool cheak(string& s,int begin,int end) {
        for(int i=begin,j=end;i<j;i++,j--) // 从两头开始向中间检查
            if(s[i]!=s[j]) // 如果两头字符不相等,则不是回文
                return false; // 返回 false
        return true; // 所有字符都相等,返回 true
    }
    
    // 回溯函数
    void backstracking(string& s,int start) {
        if(start==s.size()) { // 如果 start 等于字符串的长度,表示已经处理完毕
            result.push_back(path); // 将当前的分割方案添加到结果中
            return ; // 返回上一层
        }
        // 从 start 开始往后查找可能的分割点
        for(int i=start;i<s.size();i++) {
            if(cheak(s,start,i)) { // 检查从 start 到 i 的子串是否是回文
                string str=s.substr(start,i-start+1); // 是,将其作为一个分割
                path.push_back(str); // 将子串添加到当前的分割方案中
            } else {
                continue; // 如果不是回文,跳过当前的字符,继续下一轮循环
            }
            backstracking(s,i+1); // 递归调用,从下一个字符开始继续分割剩余的字符串
            path.pop_back(); // 回溯,移除最后添加的子串,尝试其他可能的分割点
        }
    }
};

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

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

相关文章

C#,基于密度的噪声应用空间聚类算法(DBSCAN Algorithm)源代码

1 聚类算法 聚类分析或简单聚类基本上是一种无监督的学习方法&#xff0c;它将数据点划分为若干特定的批次或组&#xff0c;使得相同组中的数据点具有相似的属性&#xff0c;而不同组中的数据点在某种意义上具有不同的属性。它包括许多基于差分进化的不同方法。 E、 g.K-均值…

kafka文件存储机制和消费者

1.broker文件存储机制 去查看真正的存储文件&#xff1a; 在/opt/module/kafka/datas/ 路径下 kafka-run-class.sh kafka.tools.DumpLogSegments --files ./00000000000000000000.index 如果是6415那么这个会存储在563的log文件之中&#xff0c;因为介于6410和10090之间。 2.…

STM32使用FlyMcu串口下载程序与STLink Utility下载程序

文章目录 前言软件链接一、FlyMcu串口下载程序原理优化手动修改跳线帽选项字节其他功能 二、STLink Utility下载程序下载程序选项字节固件更新 前言 本文主要讲解使用FlyMcu配合USART串口为STM32下载程序、使用STLink Utility配合STLink为STM32下载程序&#xff0c;以及这两个…

Stable Diffusion 模型分享:AAM XL (Anime Mix)(动漫截屏风格 XL)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八 下载地址 模型介绍 AAM XL (Anime Mix) 是一个动漫截屏风格的模型&#xff0c;是 AAM - AnyLoRA Anime Mix 模…

【办公类-25-01】20240302 UIBOT上传 ”班级主页-育儿知识(家园小报)“

作品展示&#xff1a; 一、背景需求&#xff1a; 本学期制作了 “育儿知识&#xff08;家园小报&#xff09;”合并A4内容 【办公类-22-08】周计划系列&#xff08;4&#xff09;“育儿知识&#xff08;家园小报&#xff09;“ &#xff08;2024年调整版本&#xff09;-CSDN博…

【Qt学习笔记】(四)Qt窗口

Qt窗口 1 菜单栏1.1 创建菜单栏1.2 在菜单栏中添加菜单1.3 创建菜单项1.4 在菜单项之间添加分割线1.5 给菜单项添加槽函数1.6 给菜单项添加快捷键 2 工具栏2.1 创建工具栏2.2 设置停靠位置2.3 设置浮动属性2.4 设置移动属性2.5 添加 Action 3 状态栏3.1 状态栏的创建3.2 在状态…

【高级数据结构】Trie树

原理 介绍 高效地存储和查询字符串的数据结构。所以其重点在于&#xff1a;存储、查询两个操作。 存储操作 示例和图片来自&#xff1a;https://blog.csdn.net/qq_42024195/article/details/88364485 假设有这么几个字符串&#xff1a;b&#xff0c;abc&#xff0c;abd&…

基于springboot+vue的高校教师科研管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Redis高级特性和应用(发布、订阅、Stream、慢查询、Pipeline、事务、Lua)

Redis高级特性和应用 发布和订阅 Redis提供了基于“发布/订阅”模式的消息机制&#xff0c;此种模式下&#xff0c;消息发布者和订阅者不进行直接通信,发布者客户端向指定的频道( channel)发布消息&#xff0c;订阅该频道的每个客户端都可以收到该消息。 操作命令 Redis主要…

手写 Attention 迷你LLaMa2——LLM实战

https://github.com/Yuezhengrong/Implement-Attention-TinyLLaMa-from-scratch 1. Attention 1.1 Attention 灵魂10问 你怎么理解Attention&#xff1f; Scaled Dot-Product Attention中的Scaled&#xff1a; 1 d k \frac{1}{\sqrt{d_k}} dk​ ​1​ 的目的是调节内积&…

OpenAI划时代大模型——文本生成视频模型Sora作品欣赏(十三)

Sora介绍 Sora是一个能以文本描述生成视频的人工智能模型&#xff0c;由美国人工智能研究机构OpenAI开发。 Sora这一名称源于日文“空”&#xff08;そら sora&#xff09;&#xff0c;即天空之意&#xff0c;以示其无限的创造潜力。其背后的技术是在OpenAI的文本到图像生成模…

BUGKU bp

打开环境&#xff0c;他提示了弱密码top1000&#xff0c;随便输入密码123抓包爆破 发现长度都一样&#xff0c;看一下响应发现一段js代码&#xff0c;若r值为{code: bugku10000}&#xff0c;则会返回错误&#xff0c;通过这一句“window.location.href success.php?coder.cod…

【软考】设计模式之访问者模式

目录 1. 说明2. 应用场景3. 结构图4. 构成5. java示例5.1 喂动物5.1.1 抽象访问者5.1.2 具体访问者5.1.3 抽象元素5.1.4 具体元素5.1.5 对象结构5.1.6 客户端类5.1.7 结果示例 5.2 超市销售系统5.2.1 业务场景5.2.2 业务需求类图5.2.3 抽象访问者5.2.4 具体访问者5.2.5 抽象元素…

实战:Oracle Weblogic 11g配置无密码启动,启动关闭脚本,修改节点内存

导读 上篇博文介绍了Oracle Weblogic 11g的安装部署&#xff0c;本文介绍Weblogic安装后的基本配置 包括&#xff1a;设置weblogic启动关闭的无密码验证&#xff0c;启动关闭脚本&#xff0c;修改默认的节点内存。 1、配置无密码启动 [weblogicw1 base_domain]$ cd servers/ […

C#,无监督的K-Medoid聚类算法(K-Medoid Algorithm)与源代码

1 K-Medoid算法 K-Medoid&#xff08;也称为围绕Medoid的划分&#xff09;算法是由Kaufman和Rousseeuw于1987年提出的。中间点可以定义为簇中的点&#xff0c;其与簇中所有其他点的相似度最小。 K-medoids聚类是一种无监督的聚类算法&#xff0c;它对未标记数据中的对象进行聚…

计算机网络|Socket

文章目录 Socket并发socket Socket Socket是一种工作在TCP/IP协议栈上的API。 端口用于区分不同应用&#xff0c;IP地址用于区分不同主机。 以下是某一个服务器的socket代码。 其中with是python中的一个语法糖&#xff0c;代表当代码块离开with时&#xff0c;自动对s进行销毁…

Java 石头剪刀布小游戏

一、任务 编写一个剪刀石头布游戏的程序。程序启动后会随机生成1~3的随机数&#xff0c;分别代表剪刀、石头和布&#xff0c;玩家通过键盘输入剪刀、石头和布与电脑进行5轮的游戏&#xff0c;赢的次数多的一方为赢家。若五局皆为平局&#xff0c;则最终结果判为平局。 二、实…

chrome选项页面options page配置

options 页面用以定制Chrome浏览器扩展程序的运行参数。 通过Chrome 浏览器的“工具 ->更多工具->扩展程序”&#xff0c;打开chrome://extensions页面&#xff0c;可以看到有的Google Chrome扩展程序有“选项Options”链接&#xff0c;如下图所示。单击“选项Options”…

Redis 命令全解析之 List类型

文章目录 命令RedisTemplate API使用场景 Redis 的 List 是一种有序、可重复、可变动的数据结构&#xff0c;它基于双向链表实现。在Redis中&#xff0c;List可以存储多个相同或不同类型的元素&#xff0c;每个元素在List中都有一个对应的索引位置。这使得List可以用来实现队列…

Java中线程安全的集合类

在先前的文章中我们已经讲过了原子类(线程安全的基本类型&#xff0c;基于CAS实现)&#xff0c;详见常见锁策略&#xff0c;synchronized内部原理以及CAS-CSDN博客 &#xff0c;我们在来讲一下集合类&#xff0c;在原来的集合类&#xff0c;大多数是线程不安全的&#xff0c;虽…