leetcode 困难 —— 分割回文串 II(dp)

题目:
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文。
返回符合要求的 最少分割次数 。

题解:
考虑 dp(字符串类型题目,经常用 dp)
dp[i] 为 字符串 0 到 i 的最少分割次数
那么我们如何利用之前的 dp[k](k < i) 呢
假如 字符串 k 到 i 为回文 (flag[k][i] == true),是不是 dp[i] = dp[k] + 1
建立状态转移方程 dp[i] = min(dp[0], … ,dp[i - 1](前提为dp[k][i] 为回文)) + 1

怎么快速得到 字符串 k 到 i 是否为回文呢(flag[k][i] == true)
进行预处理
如果 s[i] == s[j] && flag[i + 1][j - 1] 则 flag[i][j] 为 true(是回文)
两种遍历来预处理:

i 为子字符串的长度,j 为子字符串起点

bool flag[2005][2005] = { false };
for(int i = 0; i < s.size(); i++) {
	for(int j = 0; j + i < s.size(); j++) {
	     if(i == 0) {
	         flag[j][j + i] = true;
	     }
	     else if(i == 1) {
	         if(s[j] == s[j + i]) flag[j][j + i] = true;
	         else flag[j][j + i] = false;
	     }
	     else {
	         flag[j][j + i] = (s[j] == s[j + i]) && flag[j + 1][j + i - 1];
	     }
	 }
}


从后往前预处理

vector<vector<int>> g(n, vector<int>(n, true));
for (int i = n - 1; i >= 0; --i) {
   	for (int j = i + 1; j < n; ++j) {
       	g[i][j] = (s[i] == s[j]) && g[i + 1][j - 1];
   	}
}

代码如下:

class Solution {
public:
    bool flag[2005][2005] = { false };
    int dp[2005] = { 0 };
    int minCut(string s) {
        for(int i = 0; i < s.size(); i++) {
            for(int j = 0; j + i < s.size(); j++) {
                if(i == 0) {
                    flag[j][j + i] = true;
                }
                else if(i == 1) {
                    if(s[j] == s[j + i]) flag[j][j + i] = true;
                    else flag[j][j + i] = false;
                }
                else {
                    flag[j][j + i] = (s[j] == s[j + i]) && flag[j + 1][j + i - 1];
                }
            }
        }
        for(int i = 0; i < s.size(); i++) {
            dp[i] = INT_MAX;
            if(flag[0][i] == true) {
                dp[i] = 1;
            }
            else {
                for(int j = 0; j < i; j++) {
                    if(flag[j + 1][i] == true) {
                        dp[i] = min(dp[i], dp[j] + 1);
                    }
                }
            }
        }
        return dp[s.size() - 1] - 1;
    }
};

猜你喜欢

转载自blog.csdn.net/m0_52212261/article/details/129460772