• Leetcode 132. 分割回文串 II dp


    地址  https://leetcode-cn.com/problems/palindrome-partitioning-ii/

    给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
    
    返回符合要求的最少分割次数。
    
    示例:
    
    输入: "aab"
    输出: 1
    解释: 进行一次分割就可将 s 分割成 ["aa","b"] 这样两个回文子串。

    解答 :

    这题同上一题131 分割回文串比较类似,但是在时间上要求更高

    同样的 我们使用dp[i][j]表示 字符串i到j是否是回文字符串

    但是即使我们有了这样的dp数组,如果使用dfs去尝试各种分割回文字符串的组合,依旧会超时tle

    我们可以发现   1~n的字符串中 如何切割最小次数的回文字符串  其实是依赖于前面 1~n-1 ,1~n-2等子字符串的切割方案的 ,

    而且1~n的字符串切割方案是不影响前面的切割方案的结果。 我们依旧尝试使用dp 。

     

    我们就是根据K能和前面字符串组成回文的组合(查询dp) 计算出最小切割数即可

    转移方程

    countdp[i]  表示字符串的子字符串0~i最小切割数

    if(dp[i][j] == 1 )  //如果字符串s的子字符串i到j 是回文

    countdp[j] = countdp[i]+1; //多切一次

    代码如下

    class Solution {
    public:
        vector<vector<int>> dp;
        int ans = 9999999;
        void initDp(const string& s)
        {
          //计算dp[i][j] 字符串s的i到j的子字符串是否是回文 dp
    = vector<vector<int>>(s.size() + 10, vector<int>(s.size() + 10)); for (int i = 0; i < s.size(); i++) { dp[i][i] = 1; } for (int i = 0; i < s.size() - 1; i++) { int l = i - 1; int r = i + 1; while (l >= 0 && r < s.size() && s[l] == s[r]) { dp[l][r] = 1; l--; r++; } l = i - 1; r = i + 2; if (s[i] == s[i + 1]) dp[i][i + 1] = 1; while (l >= 0 && r < s.size() && s[l] == s[r] && s[i] == s[i + 1]) { dp[i][i + 1] = 1; dp[l][r] = 1; l--; r++; } } } int minCut(string s) { initDp(s); int count[2000]; memset(count, 0x3f, sizeof count); count[0] = 0;
        //每次新加入的字符串和前面的字符能否组成回文,如果可以 计算下当前的最小切割数
    for (int i = 1; i < s.size(); i++) { count[i] = count[i - 1] + 1; for (int j = i-1; j >= 0; j--) { if (dp[j][i] == 1 && j != 0) { count[i] = min(count[i], count[j-1]+1); } else if (dp[j][i] == 1 && j == 0) { count[i] = 0; } } } return count[s.size()-1]; } };
  • 相关阅读:
    java~用域名回显照片
    java~-照片--用流回显源码
    java表单+多文件上传~~源代码
    java~生成二维码源代码
    html页面悬浮框--左边动画(隐藏凸出)---css设置
    html页面悬浮框--右边动画(隐藏凸出)---css设置
    java编写二维码
    java上传---表单+多文件上传
    js--a标签带参数href取值
    爬虫杂记
  • 原文地址:https://www.cnblogs.com/itdef/p/14308468.html
Copyright © 2020-2023  润新知