回溯 - 回文子串

📘 回文划分(Palindrome Partitioning)学习笔记


🧠 题目简介

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


💡 解题思路

1. 回溯(Backtracking)

  • 每次从字符串 s 的当前位置尝试所有可能的子串;
  • 只选择那些是回文的子串;
  • 然后递归处理剩余部分;
  • 递归结束时,将当前路径记录下来;
  • 过程中用 path 记录当前方案,result 保存所有结果。

2. 判断回文

用双指针从两边向中间扫描,若所有字符对应相等,则是回文串。


🔧 源码实现(C++)

#include <iostream>
#include <vector>
#include <string>
using namespace std;

// 判断是否是回文串
bool isPalindrome(const string& s) {
    int left = 0, right = s.length() - 1;
    while (left < right) {
        if (s[left] != s[right]) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

// 回溯函数
void backtrack(const string& s, int start, vector<string>& path, vector<vector<string>>& result) {
    if (start == s.length()) {
        result.push_back(path);  // 记录当前合法的分割方案
        return;
    }
    for (int end = start + 1; end <= s.length(); end++) {
        string substr = s.substr(start, end - start);
        if (isPalindrome(substr)) {
            path.push_back(substr);  // 选择当前回文子串
            backtrack(s, end, path, result);  // 递归处理剩余部分
            path.pop_back();  // 回溯
        }
    }
}

// 主函数:获取所有回文划分方案
vector<vector<string>> partition(string s) {
    vector<vector<string>> result;
    vector<string> path;
    backtrack(s, 0, path, result);
    return result;
}

// 程序入口
int main() {
    string s;
    cin >> s;
    vector<vector<string>> result = partition(s);
    for (const auto& res : result) {
        for (const auto& str : res) {
            cout << str << " ";
        }
        cout << endl;
    }
    return 0;
}

🔍 示例分析

输入:

aab

输出:

a a b
aa b

解释:aab 的所有回文划分为:

  1. ["a", "a", "b"]
  2. ["aa", "b"]

📝 重点总结

项目 说明
算法核心 回溯(Backtracking)
判断回文 双指针法
数据结构 vector<vector<string>> 存结果
时间复杂度 最坏为 O(2ⁿ),需遍历所有子串组合
posted @ 2025-04-25 18:54  vv大人  阅读(25)  评论(0)    收藏  举报