当前位置: 首页 > article >正文

131. 分割回文串-两种回溯思路

       

        我们可以将字符串分割成若干回文子串,返回所有可能的方案。如果将问题分解,可以表示为分割长度为n-1的子字符串,这与原问题性质相同,因此可以采用递归方法解决。

        为什么回溯与递归存在联系?在解决这个问题时,我们首先从短字符串开始构建(递的过程),当构造到最长字符串时,需要尝试其他方案(归的过程,即回溯)。

        思路一:可以将每两个字符之间的位置视为一个可选的分割点。选择或不选择每个分割点会产生不同的字符串组合。例如,在示例一中,这种思路会产生四种不同的分割方案。

                ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​

       

        关于递归边界条件的写法:使用下标i表示当前位置。当i达到字符串长度时,说明分割完成,此时将当前方案存入ans列表。

对于非边界情况:

  1. 选择当前位置作为分割点:

    • 若当前子串是回文,则将其加入临时方案path
    • 递归处理i+1位置
    • 递归完成后需恢复现场,弹出path最后一个元素(回溯操作)
  2. 不选择当前位置作为分割点:

    • 直接递归处理i+1位置
class Solution {
public:vector<vector<string>> ans;vector<string> path;bool isPalindrome(string s,int left,int right) {while (left < right) {if (s[left++] != s[right--]) {return false;}}return true;}void dfs(int i,int n,string& s,int start) {if (i == n) {ans.emplace_back(path);return;}if (i < n - 1) dfs(i + 1,n,s,start);if(isPalindrome(s,start,i)) {path.push_back(s.substr(start,i - start + 1));dfs(i + 1,n,s,i + 1);path.pop_back();}}vector<vector<string>> partition(string s) {dfs(0,s.size(),s,0);return ans;}
};

        思路二,答案的视角(枚举子串的结束位置)

        我们以子串的结束位置j为基准,将当前回文子串加入候选路径,然后递归处理从j+1到n-1位置的剩余字符串分割问题。

class Solution {
public:vector<vector<string>> ans;vector<string> path;bool isPalindrome(string s,int left,int right) {while (left < right) {if (s[left++] != s[right--]) {return false;}}return true;}void dfs(int i,int n,string& s) {if (i == n) {ans.emplace_back(path);return;}for(int j = i;j < n;j++) {if (isPalindrome(s,i,j)) {path.push_back(s.substr(i, j - i + 1));dfs(j + 1,n,s);path.pop_back();}}}vector<vector<string>> partition(string s) {dfs(0,s.size(),s);return ans;}
};

        时间复杂度:O(n*2^n),递归次数为逗号的子集的个数,也就是2^n,在判断是否是会回文需要O(n)时间所以,总时间为O(n2^n)

        空间复杂度:O(n)

http://www.lryc.cn/news/2396986.html

相关文章:

  • [Java恶补day13] 53. 最大子数组和
  • 摩尔投票算法原理实现一文剖析
  • springboot项目下面的单元测试注入的RedisConnectionFactory类redisConnectionFactory值为什么为空呢?
  • MyBatis操作数据库(2)
  • C++面向对象(二)
  • 【C语言入门级教学】冒泡排序和指针数组
  • shell脚本中常用的命令
  • Nuxt3部署
  • 网络攻防技术一:绪论
  • 【人工智能】deepseek七篇论文阅读笔记大纲
  • unix/linux source 命令,在当前的 Shell 会话中读取并执行指定文件中的命令
  • [leetcode] 二分算法
  • imgsz参数设置
  • 【算法】分支限界
  • 使用 C/C++ 和 OpenCV 调用摄像头
  • 历史数据分析——广州港
  • 数据库管理与高可用-MySQL全量,增量备份与恢复
  • 从gitee仓库中恢复IDEA项目某一版本
  • 用dayjs解析时间戳,我被提了bug
  • [git每日一句]Changes not staged for commit
  • 架构师面试题整理
  • 类和对象:实现日期类
  • 基于springboot的运动员健康管理系统
  • 华为云Flexus+DeepSeek征文 | 初探华为云ModelArts Studio:部署DeepSeek-V3/R1商用服务的详细步骤
  • 下载即转化的商业密码:解析华为应用商店CPD广告的智能投放逻辑
  • 分布式锁和数据库锁完成接口幂等性
  • 浅谈JMeter之常见问题Address already in use: connect
  • 【机器学习基础】机器学习入门核心算法:随机森林(Random Forest)
  • 【深度学习】12. VIT与GPT 模型与语言生成:从 GPT-1 到 GPT4
  • 常规算法学习