leetcode 131. Palindrome Partitioning 、132. Palindrome Partitioning II

131. Palindrome Partitioning 

一个字符串,通过不同的切分找到所有切分后的子字符串都是回文的可能性

substr使用的是坐标值,不使用.begin()、.end()这种迭代器

使用dfs,类似于subsets的题,每次判断要不要加入这个数

start每次是起始的位置,判断当前位置到起始位置是不是回文

class Solution {
public:
    vector<vector<string>> partition(string s) {
        vector<vector<string> > result;
        if(s.empty())
            return result;
        vector<string> res;
        int start = 0;
        partition(s,result,res,start);
        return result;
    }
    void partition(string s,vector<vector<string>>& result,vector<string>& res,int start){
        if(start == s.size()){
            result.push_back(res);
            return;
        }
        for(int i = start;i < s.size();i++){
            if(!ispalindrome(s,start,i))
                continue;
            res.push_back(s.substr(start,i - start + 1));
            partition(s,result,res,i+1);
            res.pop_back();
        }
    }
    
    bool ispalindrome(string s,int start,int end){
        while(start < end){
            if(s[start++] != s[end--])
                return false;
        }
        return true;
    }
};

 

132. Palindrome Partitioning II

切分字符串,找到最小切分次数让所有的子字符串都是回文

 

这种方法是否回文和dp一起做了。dp[i]表示当前位置最小的切分次数。

每次先初始化先初始化为要切分i次,然后从前往后找,找到符合的然后更新最小值 

class Solution {
public:
    int minCut(string s) {
        int n = s.size();
        vector<int> dp(n);
        vector<vector<bool> > flag(n,vector<bool>(n));
        for(int i = 0;i < n;i++){
            dp[i] = i;
            for(int j = 0;j <= i;j++){
                if(s[i] == s[j] && (i - j < 2 ||flag[i-1][j+1])){
                    flag[i][j] = true;
                    dp[i] = j == 0 ? 0 :min(dp[i],dp[j-1] + 1);
                }
            }
        }
        return dp[n-1];
    }
};

老方法,这种方法是把所有子串的回文串先存储起来,然后再进行dp

class Solution {
public:
    int minCut(string s) {
        int length = s.length();
        if(length <= 0)
            return 0;
        vector<vector<bool>> flag(length+1,vector<bool>(length+1));
        for(int i = 1;i <= length;i++){
            flag[i][i] = true;
            if(i < length){
                if(s[i-1] == s[i])
                    flag[i][i+1] = true;
                else
                    flag[i][i+1] = false;
            }
        }
        for(int j = 1;j <= length-2;j++){
            for(int k = 1;k <= length-j-1;k++){
                if(s[k-1] == s[k+j] && flag[k+1][k+j] == true)
                    flag[k][k+j+1] = true;
                else
                    flag[k][k+j+1] = false;
            }
        }
        vector<int> result(length+1);
        result[0] = -1;
        for(int i = 1;i <= length;i++){
            result[i] = i-1;
            for(int j = i-1;j >= 0;j--){
                if(flag[j+1][i] == true){
                    if(result[j] + 1 < result[i])
                        result[i] = result[j] + 1;
                }
            }
        }
        return result[length];
    }
};

 

posted @ 2019-04-13 15:40  有梦就要去实现他  阅读(217)  评论(0编辑  收藏  举报