zoukankan      html  css  js  c++  java
  • LeetCode132:分割回文串

    给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

    返回符合要求的最少分割次数。

    示例:

    输入: "aab"
    输出: 1
    解释: 进行一次分割就可将 s 分割成 ["aa","b"] 这样两个回文子串

    与131题目类似,但是用递归的话在某些测例上会超时,因此考虑使用dp

    使用dp,首先考虑回文的特点,从头与从尾开始,对应点的字符相等。

    对一个i~j的字符串,如果我们已经判断完i+1~j-1是否为回文了,就不用重新一个个对应判断了。只要s[i]==s[j]且i+1~j-1是回文串,就可以直接判断它为回文。

    因此:

    状态定义:table[i][j]----->从i到j的子串是否为回文串

    状态转移:

    1).s[i]!=s[j]---->table[i][j]=0。i~j非回文

    2).s[i]==s[j]:

      a).j-i<=1,即i和j重合或相邻,此时为回文串。

      b).table[i+1][j-1]如果为回文,则table[i][j]=1,否则非回文。

    以上状态转移方程即可解得回文串的整个分布。

    同时,题目要求的是解出最小分割次数。

    在求解i~n-1中间的回文串状态时可以同时求出它的最小分割情况。

    定义另外一个状态转移方程:

    状态定义:dp[i]---->i~n-1中最小分割次数

    状态转移方程:

    1)i==n-1:在最后,此时应该为0

    2)i!=n-1:dp[i]=min(dp[i],1+dp[j+1])---->i~j为回文串,i~n-1的最小分割次数应该是到j分割一次后,加上dp[j+1](也就是j+1~n-1的最小分割次数)。再通过一个min来选择其中最小的分割方案。

    class Solution {
    public:
        int minCut(string s) {
            vector<vector<int>> table(s.size(),vector<int>(s.size(),0));
    		vector<int> dp(s.size());
    		for(int i=s.size()-1;i>=0;i--)//aabaa
    		{
    			dp[i]=INT_MAX;
    			for(int j=i;j<s.size();j++)
    			{
    				if(s[i]==s[j]&&((j-i<=1)||(table[i+1][j-1]==1)))
    				{
    					table[i][j]=1;
    					if(j==s.size()-1)
    						dp[i]=0;
    					else
    					{
    						dp[i]=min(dp[i],1+dp[j+1]);
    					}
    				}
    			}
    		}
    		return dp[0];
        }
    };
    

      

  • 相关阅读:
    3组-Alpha冲刺-1/6
    3组 需求分析报告
    结对编程作业
    3组 团队展示
    8组-Alpha冲刺-1/6
    8组 需求分析报告
    刘凌斌 1.3
    结对编程作业
    8组 团队介绍与选题报告
    3组-Alpha冲刺-1/6
  • 原文地址:https://www.cnblogs.com/lxy-xf/p/11158445.html
Copyright © 2011-2022 走看看