leetcode 131.分割回文串

leetcode 131.分割回文串

题干

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

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

示例 2:
输入:s = “a”
输出:[[“a”]]

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

题解

数据量小得一,字符串长度甚至<=16,那就不用多想了,直接深搜回溯即可。

class Solution {
public:
    vector<vector<string> > ans;

    bool isPalindrome(string& s){
        int n = s.length();
        for(int i = 0 ; i <= n / 2 - 1; ++i){
            if(s[i] != s[n - i - 1]) return false;
        }
        return true;
    }

    void dfs(vector<vector<string> >& ans,string& s,int leftBound,vector<string> res){
        int n = s.length();
        if(leftBound >= n){
            ans.push_back(res);
        }
        string temp = "";
        for(int i = 0 ; i < n - leftBound ; ++i){
            temp += s[leftBound+i];
            if(isPalindrome(temp)){
                res.push_back(temp);
                dfs(ans,s,leftBound+i+1,res);
                res.pop_back();
            }
        }
        return;
    }

    vector<vector<string>> partition(string s) {
        int n = s.length();
        dfs(ans,s,0,{});
        return ans;
    }
};

这里也可以使用动态规划来预处理s的全部子串,来检查子串是不是回文串(16位的子串也就2^16种)
dp的下标范围是从小到大不断扩张的,所以我们将i固定于右界不断向左,j则遍历每个i的右侧区域,以此保证状态转移过程中内部涉及的子串已经全部计算过。
将j固定于左界,i遍历j的左侧区域也是可以的。

class Solution {
public:
    vector<vector<string> > ans;
    vector<vector<bool> > isPalindrome;

    void dfs(vector<vector<string> >& ans,string& s,int leftBound,vector<string> res){
        int n = s.length();
        if(leftBound >= n){
            ans.push_back(res);
        }
        string temp = "";
        for(int i = 0 ; i < n - leftBound ; ++i){
            temp += s[leftBound+i];
            if(isPalindrome[leftBound][leftBound+i] == 1){
                res.push_back(temp);
                dfs(ans,s,leftBound+i+1,res);
                res.pop_back();
            }
        }
        return;
    }

    vector<vector<string>> partition(string s) {
        int n = s.length();
        isPalindrome.resize(n, vector<bool>(n, true));
        isPalindrome[0][0] = 1;
        for(int i = n - 1 ; i >= 0 ; --i){
            for(int j = i + 1 ; j < n ; ++j){
                isPalindrome[i][j] = isPalindrome[i+1][j-1] && (s[i] == s[j]);
            }
        }
        dfs(ans,s,0,{});
        return ans;
    }
};

你可能感兴趣的:(leetcode,leetcode,dfs,c++,回溯算法,字符串)