zoukankan      html  css  js  c++  java
  • leetcode 132 分割回文串II(dp)

    题目描述:

     题解:一开始的时候想着用区间dp。dp[i][j]表示s[i~j]分割为会文子串的最少分割次数。状态转移也很简单,要么s[i~j]本身是回文串不需要分割;

    要么枚举分隔点K,dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+1);代码如下:

    class Solution {
    public:
        int minCut(string s) {
            int Len = s.length();
            int dp[Len][Len];
            for(int i=0;i<Len;i++)
            {
                for(int j=0;j<Len;j++) dp[i][j] = INT_MAX;
            }
            for(int i=0;i<Len;i++) dp[i][i] = 0;
    
            for(int l = 2;l<=Len;l++)
            {
                for(int i = 0;i+l-1<Len;i++)
                {
                    int j = i+l-1;
                    
                    if(s[i] == s[j])
                    {
                        if(l == 2 || dp[i+1][j-1] == 0) 
                        {
                            // cout <<i <<" " << j <<endl;
                            dp[i][j] = 0;
                            continue;
                        }   
                    }
    
                    for(int k = i;k<j;k++)
                    {
                        dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+1);
                    }
                }
            } 
            
            return dp[0][Len-1];
        }
    };

     但是这么做的话时间复杂度为o(n^3),果不其然超时了。可以改进的地方有两点:

    1. 枚举K的时候,不需要遍历所有情况,只需要枚举s[i~k]或者s[k+1~j]有一个为回文串的情况。

    2. 不需要用区间dp的板子,二维的dp三维的遍历,时间复杂度太高了。

    新定义一个dp:dp[i]表示s[0~i]分割为回文子串需要的最少分割次数。状态转移结合改进点1进行处理就好。

    值得提一下的时候这里判断一个子串是不是回文子串,可以预先用一个二维的dp处理掉。预处理的dp我借鉴了一下别人的代码,自己想的状态转移又是O(n^3)的.....

    AC代码:

    class Solution {
    public:
        int minCut(string s) {
            int Len = s.length();
            int judge[Len][Len];
            for(int i = 0;i<Len;i++)
            {
                for(int j=0;j<Len;j++) judge[i][j] = 0;
            }
            
         // 判断s[left][right]是不是回文串,由于judge[left][right]需要根据judge[left+1][right-1]转移
         // 那么在遍历的时候,第一维遍历right,这样就能保证有序的进行状态转移
    for(int right = 0;right<Len;right++) { for(int left = 0;left<=right;left++) { if(left == right) judge[left][right] = 1; else { if(right - left == 1) { if(s[left] == s[right]) judge[left][right] = 1; } else { if(s[left] == s[right]) judge[left][right] = judge[left+1][right-1]; } } } } //cout << judge[0][2] <<endl; int dp[Len]; dp[0] = 0; for(int i=1;i<Len;i++) dp[i] = INT_MAX; for(int i=1;i<Len;i++) { if(judge[0][i] == 1) { dp[i] = 0; continue; } for(int j=0;j<i;j++) { if(judge[j+1][i] == 1) { dp[i] = min(dp[i],dp[j]+1); } } } return dp[Len-1]; } };
  • 相关阅读:
    java的各种日志框架
    (4)一起来看下mybatis框架的缓存原理吧
    (3)一起来看下使用mybatis框架的select语句的源码执行流程吧
    Markdown基本语法
    openstack中使用linux_bridge实现vxlan网络
    python基础—第一句Python语句以及条件语句
    Java内存详解
    Java工具类练习题和答案
    面向过程和面向对象
    网页设计案例
  • 原文地址:https://www.cnblogs.com/z1141000271/p/12461186.html
Copyright © 2011-2022 走看看