玩命加载中 . . .

分割回文串


描述

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

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

示例 1:

输入:s = “aab”
输出:[[“a”,”a”,”b”],[“aa”,”b”]]
示例 2:

输入:s = “a”
输出:[[“a”]]

提示:

1 <= s.length <= 16
s 仅由小写英文字母组成

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/palindrome-partitioning
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

C++代码

class Solution {
public:
    vector<vector<string>> partition(string s) {
        vector<vector<string>> res; // 用于存储结果
        vector<string> path; // 用于存储当前的分割方案
        dfs(s, 0, path, res); // 深度优先搜索
        return res;
    }

    void dfs(string s, int start, vector<string>& path, vector<vector<string>>& res) {
        if (start == s.size()) { // 如果已经遍历完整个字符串
            res.push_back(path); // 将当前分割方案加入结果中
            return;
        }
        for (int i = start; i < s.size(); i++) { // 从start开始遍历到字符串末尾
            if (isPalindrome(s, start, i)) { // 如果[start, i]这个子串是回文串
                path.push_back(s.substr(start, i - start + 1)); // 将这个子串加入当前分割方案
                dfs(s, i + 1, path, res); // 递归处理下一段字符串
                path.pop_back(); // 回溯,将刚刚加入的子串从当前分割方案中删除
            }
        }
    }

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

这道题的思路是深度优先搜索,具体来说,我们从字符串的开头开始遍历,对于每个位置,我们考虑以它为起点的所有子串。如果这个子串是回文串,我们就将它加入当前的分割方案中,然后递归处理下一段字符串。如果当前的分割方案已经包含了整个字符串,那么我们就将它加入结果中。

在实现中,我们使用了一个辅助函数isPalindrome来判断一个子串是否为回文串,它的实现很简单,就是从两端开始往中间扫描,如果发现不相等的字符,就说明这个子串不是回文串。

在深度优先搜索的过程中,我们使用了两个辅助变量pathres,分别用来存储当前的分割方案和所有的结果。每次递归调用时,我们都将当前的分割方案作为参数传入,如果当前的分割方案已经包含了整个字符串,那么我们就将它加入结果中。注意,在递归处理下一段字符串之前,我们需要将刚刚加入的子串从当前分割方案中删除,这个操作叫做回溯。

Python代码

class Solution:
    def partition(self, s: str) -> List[List[str]]:
        res = [] # 用于存储结果
        path = [] # 用于存储当前的分割方案
        self.dfs(s, 0, path, res) # 深度优先搜索
        return res
    
    def dfs(self, s: str, start: int, path: List[str], res: List[List[str]]):
        if start == len(s): # 如果已经遍历完整个字符串
            res.append(path[:]) # 将当前分割方案加入结果中
            return
        for i in range(start, len(s)): # 从start开始遍历到字符串末尾
            if self.isPalindrome(s, start, i): # 如果[start, i]这个子串是回文串
                path.append(s[start:i+1]) # 将这个子串加入当前分割方案
                self.dfs(s, i+1, path, res) # 递归处理下一段字符串
                path.pop() # 回溯,将刚刚加入的子串从当前分割方案中删除
    
    def isPalindrome(self, s: str, left: int, right: int) -> bool: # 判断子串是否为回文串
        while left < right:
            if s[left] != s[right]:
                return False
            left += 1
            right -= 1
        return True

文章作者: Jack Tim
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Jack Tim !
评论
  目录