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; // 返回 falsereturn 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(); // 回溯,移除最后添加的子串,尝试其他可能的分割点}}
};

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

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

相关文章

#WEB前端(DIV、SPAN)

1.实验&#xff1a;DIV、SPAN 2.IDE&#xff1a;VSCODE 3.记录&#xff1a; 类? 4.代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdev…

详细讲解Docker架构的原理、功能以及如何使用

一、简介 1、了解docker的前生LXC LXC为Linux Container的简写。可以提供轻量级的虚拟化&#xff0c;以便隔离进程和资源&#xff0c;而且不需要提供指令解释机制以及全虚拟化的其他复杂性。相当于C中的NameSpace。容器有效地将由单个操作系统管理的资源划分到孤立的组中&…

Ps:历史记录面板

Ps菜单&#xff1a;窗口/历史记录 Window/History 历史记录 History面板提供了对图像编辑过程中所进行更改的深入控制&#xff0c;可以让用户回溯并查看每一步操作&#xff0c;从而允许用户轻松撤销错误或比较不同的编辑效果。 ◆ ◆ ◆ 常用操作方法与技巧 “历史记录”面板…

Redis之十:Spring Data Redis --- CrudRepository方式

SpringData Redis CrudRepository方式 Spring Data Redis 的 CrudRepository 是 Spring Data 框架中用于提供基础 CRUD&#xff08;创建、读取、更新和删除&#xff09;操作的一个接口。在与 Redis 集成时&#xff0c;尽管 Redis 是一个键值存储系统&#xff0c;并没有像关系型…

对象锁与类锁

不同锁互不影响&#xff0c;共用一个锁&#xff0c;可能会发生阻塞。 1.在修饰静态方法时&#xff0c;锁定的是当前类的 Class 对象&#xff0c;在下面的例子中就是SycTest1.class 2.当修饰非静态方法时&#xff0c;锁定的就是 this 对象&#xff0c;即当前的实例化对象 public…

基于springboot实现计算机类考研交流平台系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现计算机类考研交流平台系统演示 摘要 高校的大学生考研是继高校的高等教育更上一层的表现形式&#xff0c;教育的发展是我们社会的根本&#xff0c;那么信息技术的发展又是改变我们生活的重要因素&#xff0c;生活当中各种各样的场景都存在着信息技术的发展。…

chrome选项页面options page配置

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

如何使用数据可视化库 D3 绘制折线统计图

如题&#xff0c;如何使用数据可视化库 D3 绘制折线统计图&#xff1f; 这篇文章将通过实例来讲解如何一步一步绘制下面这样一个折线统计图&#xff0c;并带有鼠标悬浮移动的文字显示效果。 首先&#xff0c;我们来看下什么是 d3&#xff1f;移步官网&#xff1a;https://d3js.…

Apple Mobile Device Driver

Apple Mobile Device Driver (Windows 10)原来安装过&#xff0c;突然不见了&#xff0c;可以尝试一下方法。 下载 Windows 版 iTunes - 官方 Apple 支持 (中国)

网络安全-appcms-master

一、环境 gethub上面自己找appcms-master 二、开始闯关 原理&#xff1a;在评论的时候提交可以提交到管理员列表去&#xff0c;管理员一看cookie和地址就被盗走了 点进去软件后会发现提交按钮 随便提交一下看看 放到div标签里面是不是有可能可以做&#xff0c;看看后台吧 那…

详解如何保证消息队列不丢失消息(以kafka为例)

✨✨祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 一、引言 二. 持久化存储 2.1持久化存储原理&#xff1a; 2.2使用示例&#xff1a; …

【tableau学习笔记】tableau无法连接数据源

【tableau学习笔记】tableau无法连接数据源 背景&#xff1a; 学校讲到Tableau&#xff0c;兴奋下载Kaggle Excel&#xff0c;一看后缀CSV&#xff0c;导入Tableau发现报错“tableau无法连接数据源”&#xff0c;自作聪明改为后缀XLSX&#xff0c;bug依旧。 省流&#xff1a…