[leetcode] 132.Palindrome Partitioning II

Palindrome Partitioning II

Given a string s, partition s such that every substring of the partition is a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
Example:

Input: “aab”
Output: 1
Explanation: The palindrome partitioning [“aa”,“b”] could be produced using 1 cut.

解法1,dp+回文dp

一个二维数组动态规划记录是否为回文串,一个一维数组dp[i]记录s[0,i]的最小分割数
当ispalin[j][i]==1时,表示s[j,i]是回文串,那么dp[i] = dp[j-1]+1, 初始化dp[i] = i;

class Solution {
public:
    int minCut(string s) {
        int n = s.size();
        vector<vector<bool>> ispalind(n, vector<bool>(n));
        vector<int> dp(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 || ispalind[j+1][i-1])){
                    ispalind[j][i] = 1;
                    dp[i] = j==0 ? 0: min(dp[j-1]+1,dp[i]);
                }
        } 
        for(int i=0;i<n;i++)
            cout<<dp[i]<<" ";
        return dp[n-1];                                                     
    }
};

解法2

不使用二维数组来记录回文串,直接使用一个n+1维数组进行dp
dp[i]表示前i个字符子串的最小分割数,每次遍历i时,更新dp[i+len+1]和dp[i+len+2]
dp[i+len+1]更新的是以i为中心,总长度为 2len + 1 的回文串,比如 bob,此时 i=1,len=1
dp[i+len+1]更新的是i为中心之一,总长度为 2
len + 2 的回文串,比如 noon,此时 i=1,len=1。
i-len 正好是奇数或者偶数回文串的起始位置,由于我们定义的 dp[i] 是区间 [0, i-1] 的最小分割数,所以 dp[i-len] 就是区间 [0, i-len-1] 范围内的最小分割数,那么加上奇数回文串长度 2len + 1,此时整个区间为 [0, i+len],即需要更新 dp[i+len+1]。如果是加上偶数回文串的长度 2len + 2,那么整个区间为 [0, i+len+1],即需要更新 dp[i+len+2]。

class Solution {
public:
    int minCut(string s) {
        int n = s.size();
        vector<int> dp(n+1, INT_MAX);
        dp[0] = -1;
        for(int i = 0; i < n; i++){
            for(int len = 0; i-len>=0 && i+len < n && s[i-len] == s[i+len]; len++)
                dp[i+len+1] = min(dp[i+len+1], dp[i-len]+1);
            for(int len = 0; i-len>=0 && i+len+1 < n && s[i-len] == s[i+len+1]; len++)
                dp[i+len+2] = min(dp[i+len+2], dp[i-len]+1);
        } 
        for(int i=0;i<=n;i++)
            cout<<dp[i]<<" ";
        return dp[n];                                                     
    }
};

参考

https://www.cnblogs.com/grandyang/p/4271456.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值