131. 分割回文串

131. 分割回文串

题目链接:131. 分割回文串(中等)

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

回文串 是正着读和反着读都一样的字符串。

示例 1:

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

示例 2:

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

提示:

  • 1 <= s.length <= 16

  • s 仅由小写英文字母组成

解题思路

我觉得本题最大的难点在于:不知道如何将切割问题抽象为组合问题。

如下图所示,可以将切割问题抽象为一棵树形结构,for循环用来横向遍历,递归用来纵向遍历。同时递归函数参数需要 start,因为切割过的地方,不能重复切割,和组合问题也是保持一致的。从图中可以看出,当statr不小于s的长度时,就可以找到一组分割方案。当然在分割的过程中还需要判断分割产生的子串是否是回文。

C++

class Solution {
public:
    vector<vector<string>> result;
    vector<string> path;
    void backTracking(string s, int start) {
        // 当 起始位置 不小于 s 的大小,说明已经找到了一组分割方案了
        if (start >= s.size()) {
            result.push_back(path);
            return;
        }
        for (int i = start; i < s.size(); i++) {
            // 判断将被截取的字符串[start,i]是不是回文
            // 如果是,则截取并保存,继续纵向遍历
            // 如果不是,则横向遍历
            bool flag = isPalindrome(s, start, i);
            if (flag) {
                // substr(start, length) 返回一个从指定位置开始的指定长度的子字符串
                // star 所需的子字符串的起始位置 字符串中的第一个字符的索引为 0
                // lenght 在返回的子字符串中应包括的字符个数
                string str = s.substr(start, i - start + 1);
                path.push_back(str);
                backTracking(s, i + 1); // // 纵向继续找i+1为起始位置的子串
                path.pop_back(); // 回溯过程,弹出此次已填子串
            }
        }
    }
    //判断一个字符串是不是回文
    bool isPalindrome(string s, int i, int j) {
        while (i < j) {
            if (s[i] != s[j]) return false;
            i++; j--;
        }
        return true;
    }
    vector<vector<string>> partition(string s) {
       path.clear();
       result.clear();
       backTracking(s, 0);
       return result;
    }
};

JavaScript

let path = [];
let result = [];
​
const backTracking = (s, start) => {
    if (start >= s.length) {
        result.push([...path]);
        return;
    }
​
    for (let i = start; i < s.length; i++) {
        if (isPalindrome(s, start, i)) {
            let str = s.substr(start, i - start + 1);
            path.push(str);
            backTracking(s, i + 1);
            path.pop();
        }
    }
}
​
const isPalindrome = (s, i, j) => {
    while (i < j) {
        if (s[i] != s[j]) return false;
        i++;
        j--;
    }
    return true;
}
​
var partition = function(s) {
    path = [];
    result = [];
    backTracking(s, 0);
    return result;
};

 

原文地址:https://www.cnblogs.com/wltree/p/15731241.html