leetCode 131.分割回文串 + 回溯算法 + 图解 + 笔记

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

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

示例 1:

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

示例 2:

输入:s = "a"
输出:[["a"]]

>>思路和分析:

  1. 切割问题,有不同的切割方式
  2. 判断回文

代码随想录的Carl老师说:“切割问题类似组合问题”!(这段文字来自代码随想录--分割回文串)

对于字符串abcdef

  • 组合问题选取一个a之后,在bcdef中再去选取第二个,选取b之后在cdef中再选取第三个.....
  • 切割问题切割一个a之后,在bcdef中再去切割第二段,切割b之后在cdef中再切割第三段.....

>>回溯三部曲:

1).确定回溯函数参数

  • path 存放切割后回文的子串
  • result 保存 path,作为结果集
  • startIndex 来控制for循环的起始位置(表示下一轮递归遍历的起始位置),还用来表示这条切割线.(切割过的地方,不能重复切割,和组合问题也是保持一致的【这句话来自代码随想录】)
vector<vector<string>> result;
vector<string> path; // 放已经回文的子串
void backtracking (const string& s, int startIndex) // startIndex 就用来表示这条切割线

2).递归的终止条件

如果切割线切到了字符串最后面,表示找了一种切割方法,此时终止本层递归!也就是出现这种情况: startIndex >= s.size(),收集结果后直接return;

void backtracking (const string& s, int startIndex) {// 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了if (startIndex >= s.size()) {result.push_back(path);return;}
}

3).单层搜索的逻辑

>>问题(O_O)?思考:在递归循环中如何截取子串呢?

  • [startIndex,i]:左闭右闭,表示子串的起始位置和终止位置,有截取区间就可以截取子串。substr(startIndex, i - startIndex + 1);

>>问题(O_O)?思考:如何判断所截取子串是否为回文子串呢?

  1. 判断是否为回文子串:isPalindrome(s, startIndex, i),用双指针法
  2. 如果是回文,就加入在vector<string> path中,path 用来记录切割过的回文子串
for (int i = startIndex; i < s.size(); i++) {if (isPalindrome(s, startIndex, i)) { // 是回文子串// 获取[startIndex,i]在s中的子串string str = s.substr(startIndex, i - startIndex + 1);path.push_back(str);} else {                // 如果不是则直接跳过continue;}backtracking(s, i + 1); // 寻找i+1为起始位置的子串path.pop_back();        // 回溯过程,弹出本次已经添加的子串
}

注意:切割过的位置,不能重复切割,应传入下一层的起始位置为 i + 1,即

  • backtracking(s, i + 1);

 (1)判断是否为回文子串

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;}
bool isPalindrome(string s) {int left = 0,right = s.size()-1;while(left<=right) {if (s[left] != s[right]) return false;left++;right--;}return true;
}

 (2)C++代码

class Solution {
private:vector<vector<string>> result;vector<string> path; // 放已经回文的子串void backtracking (const string& s, int startIndex) {// 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了if (startIndex >= s.size()) {result.push_back(path);return;}for (int i = startIndex; i < s.size(); i++) {if (isPalindrome(s, startIndex, i)) {   // 是回文子串// 获取[startIndex,i]在s中的子串string str = s.substr(startIndex, i - startIndex + 1);path.push_back(str);} else {                                // 不是回文,跳过continue;}backtracking(s, i + 1); // 寻找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;}
};
  • 时间复杂度: O(n * 2^n)
  • 空间复杂度: O(n^2)
class Solution {
public:vector<vector<string>> result;vector<string> path; // 放已经回文的子串bool isPalindrome(string s) {int left = 0,right = s.size()-1;while(left<=right) {if (s[left] != s[right]) return false;left++;right--;}return true;}void backtracking(string s,int startIndex) {// 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了if(startIndex >= s.size()) {result.push_back(path);return;}for(int i=startIndex;i<s.size();i++) {// 获取[startIndex,i]在s中的子串string subStr = s.substr(startIndex,i-startIndex+1);if(isPalindrome(subStr)) path.push_back(subStr);// 是回文子串else continue;// 不是回文,跳过backtracking(s, i + 1); // 寻找i+1为起始位置的子串path.pop_back(); // 回溯过程,弹出本次已经添加的子串}}vector<vector<string>> partition(string s) {backtracking(s, 0);return result;}
};

 参考和推荐文章、视频:
带你学透回溯算法-分割回文串(对应力扣题目:131.分割回文串)| 回溯法精讲!_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1c54y1e7k6/?p=67&spm_id_from=pageDriver代码随想录 (programmercarl.com)icon-default.png?t=N7T8https://www.programmercarl.com/0131.%E5%88%86%E5%89%B2%E5%9B%9E%E6%96%87%E4%B8%B2.html#%E4%BC%98%E5%8C%96

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

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

相关文章

从原理和公式出发:python实现One_Way_ANOVA

文章目录 目的&#xff1a;python实现one way ANOVA 单因素方差分析1. 代码流程2. python代码实现0 主要的函数1 加载数据2 查看数据统计结果3 数据处理及可视化4 方差分析4.1 模型拟合4.2 单因素方差分析 5 Post Hoc t-test组间比较分析6 根据定义自行分解计算对比调用函数的结…

pandas-profiling / ydata-profiling介绍与使用教程

文章目录 pandas-profilingydata-profilingydata-profiling实际应用iris鸢尾花数据集分析 pandas-profiling pandas_profiling 官网&#xff08;https://pypi.org/project/pandas-profiling/&#xff09;大概在23年4月前发出如下公告&#xff1a; Deprecated pandas-profilin…

积分表二(高等数学同济版中所有的积分公式)

文章目录 含有 x − a x a \sqrt{\pm \frac{x-a}{xa}} xax−a​ ​ 或者 ( x − a ) ( b − x ) \sqrt{(x-a)(b-x)} (x−a)(b−x) ​ 的积分含有三角函数函数的积分含有反三角函数的积分 (其中 a > 0 a>0 a>0)含有指数函数的积分含有对数函数的积分含有双曲函数的…

Object常用方法

toString()&#xff1a;返回对象的字符串表示形式。hasOwnProperty(propertyName)&#xff1a;检查对象是否有指定的属性。isPrototypeOf(object)&#xff1a;检查一个对象是否是另一个对象的原型。propertyIsEnumerable(propertyName)&#xff1a;检查对象的指定属性是否可以枚…

LeetCode 4 寻找两个正序数组的中位数

题目描述 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 示例 1&#xff1a; 输入&#xff1a;nums1 [1,3], nums2 [2] 输出&#xff1a;2.0…

MediaPipe - 小记

文章目录 关于 MediaPipe 关于 MediaPipe Cross-platform, customizable ML solutions for live and streaming media. MediaPipe &#xff1a; 设备端机器学习框架 MediaPipe Studio : 提供标准化 task&#xff0c;你可以下载预训练模型来使用 MediaPipe Model Maker : 定制…

python中的字符串

字符串 字符串是编程语言中的一种基本数据类型&#xff0c;用于表示一串字符序列。在Python中&#xff0c;字符串是不可变的&#xff0c;也就是说一旦字符串被创建&#xff0c;就无法修改其中的字符。 Python中的字符串可以用单引号或双引号括起来&#xff0c;例如&#xff1…

构建SQL Server链接服务器:实现跨服务器数据访问及整合

点击上方蓝字关注我 在SQL Server数据库管理中&#xff0c;链接服务器是一项强大的功能&#xff0c;允许在一个SQL Server实例中访问另一个SQL Server实例的数据。这种功能为数据库管理员提供了灵活性&#xff0c;使其能够跨不同服务器进行数据交互&#xff0c;开辟了更多的应用…

RLHF:强化学习结合大预言模型的训练方式

RLHF (Reinforcement Learning from Human Feedback) 以强化学习方式依据人类反馈优化语言模型。 文章目录 一、简介二、一般的流程三、微调gpt介绍示例 参考文章 一、简介 强化学习从人类反馈中学习&#xff08;RLHF&#xff0c;Reinforcement Learning from Human Feedback&a…

【代码随想录】算法训练计划37

贪心 1、738. 单调递增的数字 题目&#xff1a; 输入: n 10 输出: 9 思路&#xff1a; func monotoneIncreasingDigits(n int) int {// 贪心&#xff0c;利用字符数组s : strconv.Itoa(n)ss : []byte(s)leng : len(ss)if leng < 1 {return n}for i:leng-1; i>0; i-- …

为什么不把所有的函数都定义成内联函数

内联是以代码膨胀为代价&#xff0c;仅仅省去了函数调用的开销&#xff0c;从而提高函数的执行效率。如果执行函数体内代码的时间相比于函数调用的开销较大&#xff0c;那么效率的收获会很少。另一方面&#xff0c;每一处内联函数的调用都要复制代码&#xff0c;将使程序的总代…

vscode集成git

1、首先电脑要安装git 打开git官网地址&#xff1a;Git进行下载&#xff0c;如下图界面&#xff1a; 如图片中描述&#xff1a;一般进入官网后会识别电脑对应系统&#xff08;识别出了我的电脑是Windows系统 。如果未识别到电脑系统&#xff0c;可在左侧选择自己电脑对应的系统…

主成分分析例题 (多元统计分析期末复习)

例一 给定X的协差阵&#xff0c;对其进行主成分分析, &#xff08;1&#xff09;求出每个主成分的贡献率&#xff1b; &#xff08;2&#xff09;求出每个原始变量的信息提取率&#xff1b; 解&#xff1a;对于主成分分析的题&#xff0c;一般来说&#xff0c;题目给定一个协方…

us提升到ns级精度settimeofday()到clock_settime()

精度 clock_settime()精度比settimeofday()高&#xff0c;受限制于参数的结构体&#xff0c;一个是ns级精度&#xff0c;另一个us级精度。具体两个函数原因参考如下。 int clock_settime(clockid_t clk_id, const struct timespec *tp); int settimeofday(const struct timeva…

[vue3] 使用 vite 创建vue3项目的详细流程

一、vite介绍 Vite&#xff08;法语意为 “快速的”&#xff0c;发音 /vit/&#xff0c;发音同 “veet”) 是一种新型前端构建工具&#xff0c;能够显著提升前端开发体验&#xff08;热更新、打包构建速度更快&#xff09;。 二、使用vite构建项目 【学习指南】学习新技能最…

Elasticsearch:使用 ILM 示例运行降采样 (downsampling)

如果你对降采样还不是很熟的话&#xff0c;请阅读之前的文章 “Elasticsearch&#xff1a;对时间序列数据流进行降采样&#xff08;downsampling)”。这是一个简化的示例&#xff0c;可让你快速了解降采样如何作为 ILM 策略的一部分来减少一组采样指标的存储大小。 该示例使用典…

2021年3月9日 Go生态洞察:Go开发者调研结果解读

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

java对象 转换成json字符串 工具类 jackson

jackson概述 Jackson 是一个用于处理 JSON 数据的 Java 库&#xff0c;由 FasterXML 公司开发和维护。它提供了一组功能强大的 API&#xff0c;用于在 Java 对象和 JSON 数据之间进行高效的序列化&#xff08;将对象转换为 JSON 格式&#xff09;和反序列化&#xff08;将 JSO…

获取焦点后,样式异常的处理方法

问题 在使用monaco-editor 设置代码提示未正常显示&#xff0c;提示框出现&#xff0c;看不到内容&#xff0c;如图 看不到内容&#xff0c;有两种情况&#xff1a; 情况一&#xff1a;没有得到数据&#xff0c;所以没有展示&#xff1b; 情况二&#xff1a;得到了数据&#x…

数据预处理:随机裁剪放缩

随机裁剪放缩是一种数据增强技术&#xff0c;可以在训练神经网络时增加数据的多样性&#xff0c;提高模型的泛化能力。具体来说&#xff0c;随机裁剪放缩可以通过随机裁剪和缩放原始图片来生成多个不同的训练样本&#xff0c;从而增加数据集的大小和多样性。这种技术在图像分类…