news 2026/5/26 9:15:26

回溯算法--分割回文串

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
回溯算法--分割回文串

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回 s 所有可能的分割方案。

示例: 输入: "aab" 输出: [ ["aa","b"], ["a","a","b"] ]

难点

本题的难点在于

  1. 怎么理解或者实现分割这个概念。
  2. 怎么分割的字符串怎么定义。

分割这个问题类似于组合问题,定义一个startIndex,startIndex指向那个字符就是分割的位置。

for(int i = startIndex; i < s.size(); i ++), 在对字符串进行横向遍历的时候,statrIndex 到 i 的长度不就是分割字符串。

思路

定义参数

vector<vector<string>> result; vector<string> path; // 核心的回溯函数 // s: 输入的原始字符串 // startIndex: 当前遍历的起始位置 void backtracking(const string& s, int startIndex)

递归结束条件

当分割到最后一个字符时,说明已经分割完毕,并且一定有满足条件的path,因为每个每个单个字母一定是回文串。

if(startIndex == s.size()){ // 将当前构造的分割方案 (path) 添加到最终结果 (result) 中 result.push_back(path); return; }

单层递归逻辑

首先判断分割的字符串是否为回文串,如果是,则压入path。如果不是则跳过,继续考察更长的子串。

当考察到回文串的时候,才会继续向下递归。

// 单层搜索逻辑:从 startIndex 开始,向后遍历字符串 for(int i = startIndex; i < s.size(); i ++){ // 判断从 startIndex 到 i 的子串是否是回文串 if(isPalindrome(s, startIndex, i)){ // 如果是回文串,将其加入到当前路径 (path) 中 // s.substr(startIndex, i - startIndex + 1) 截取了从 startIndex 开始,长度为 i - startIndex + 1 的子串 path.push_back(s.substr(startIndex, i - startIndex + 1)); }else{ // 如果不是回文串,则跳过,继续考察更长的子串 continue; } // 递归:进入下一层决策,起始位置变为 i + 1 backtracking(s, i + 1); // 回溯:撤销当前层的选择,将刚刚加入的子串弹出,以便探索其他可能性 path.pop_back(); }

代码

#include<iostream> #include<vector> using namespace std; // 解题的核心类 class Solution { private: vector<vector<string>> result; vector<string> path; // 核心的回溯函数 // s: 输入的原始字符串 // startIndex: 当前遍历的起始位置 void backtracking(const string& s, int startIndex){ // 基本情况(终止条件):如果起始位置已经等于字符串长度, // 说明我们已经找到了一个完整的分割方案 if(startIndex == s.size()){ // 将当前构造的分割方案 (path) 添加到最终结果 (result) 中 result.push_back(path); return; } // 单层搜索逻辑:从 startIndex 开始,向后遍历字符串 for(int i = startIndex; i < s.size(); i ++){ // 判断从 startIndex 到 i 的子串是否是回文串 if(isPalindrome(s, startIndex, i)){ // 如果是回文串,将其加入到当前路径 (path) 中 // s.substr(startIndex, i - startIndex + 1) 截取了从 startIndex 开始,长度为 i - startIndex + 1 的子串 path.push_back(s.substr(startIndex, i - startIndex + 1)); }else{ // 如果不是回文串,则跳过,继续考察更长的子串 continue; } // 递归:进入下一层决策,起始位置变为 i + 1 backtracking(s, i + 1); // 回溯:撤销当前层的选择,将刚刚加入的子串弹出,以便探索其他可能性 path.pop_back(); } } bool isPalindrome(const string& s, int i, int j){ while(i <= j){ if(s[i] != s[j]){ return false; }else{ i ++; j --; } } return true; } public: vector<vector<string>> partition(string s) { result.clear(); path.clear(); backtracking(s, 0); return result; } }; int main(){ Solution S; string s = "abcd"; vector<vector<string>> result = S.partition(s); for(auto row : result){ for(auto cols : row){ cout << cols << " "; // 打印子串 } cout << endl; // 每打印完一种方案后换行 } return 0; // 程序正常退出 }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/25 18:48:10

功率MOSFET特性分析与应用考量:以NCE0208KA为例

当选MOSFET时&#xff0c;参数权衡总是免不了的——特别是在设计那些工作在几十到上百伏电压范围的开关电源或电机驱动电路时。只看数据手册首页的电压电流值远远不够&#xff0c;在实际电路中&#xff0c;器件如何开关、发热多少、能否稳定运行&#xff0c;这些往往更关键。这…

作者头像 李华
网站建设 2026/5/26 7:20:50

python一些小细节

GIL锁&#xff1a; 当python使用多线程的时候&#xff0c; 每个线程通过请求这个锁获取运行权。 结束时归还 async/await/asyncio/gather/create_task/ThreadPool 理解asynciohttps://www.bilibili.com/video/BV1oa411b7c9?spm_id_from333.788.videopod.sections&vd_sour…

作者头像 李华
网站建设 2026/5/25 9:33:28

“零基础6个月冲进大厂,现在还来得及吗?很担心自己学不学的会

答案是&#xff1a;“来得及&#xff0c;但极具挑战&#xff0c;且需要正确的路径、极致的学习和一点点运气。”​ 这绝不是一条轻松的路&#xff0c;而是一场需要周密计划的“冲刺”。 “来得及”是因为网络安全行业人才缺口巨大&#xff0c;尤其是具备实战能力的安全工程师、…

作者头像 李华
网站建设 2026/5/26 5:57:58

据说算力高达1000 TOPS,华硕Ascent GX10深度评测——模型推理

在AI大模型遍地开花的2025年&#xff0c;算力焦虑已经成为开发者的共同话题。动辄十几万的专业工作站让个人开发者望而却步&#xff0c;而云端GPU又面临着成本高昂、数据隐私等问题。就在这个节点上&#xff0c;华硕推出了一款颇具野心的产品——Ascent GX10&#xff0c;官方宣…

作者头像 李华
网站建设 2026/5/26 5:57:39

JSP如何结合国密算法实现大文件加密存储?

咱是一名福建的“老码农”&#xff0c;最近接了个外包项目&#xff0c;客户要做大文件上传功能&#xff0c;要求还挺细——原生JS实现、20G文件传输、文件夹保留层级、加密传输存储、断点续传兼容IE9… 预算还卡在100块以内&#xff08;老板说“小项目不搞虚的”&#xff09;。…

作者头像 李华
网站建设 2026/5/26 6:18:59

JSP中如何利用分段技术实现百万文件上传优化?

&#x1f4cc; 毕业设计求生指南&#xff1a;大文件上传系统&#xff08;兼容IE8版&#xff09; &#x1f629; 现状描述 大家好&#xff0c;我是浙江某三本计算机专业的大三学生&#xff0c;马上要毕业了&#xff0c;现在被导师逼着搞一个**「支持10G文件上传的系统」**&…

作者头像 李华