Q:

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

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

示例:

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

A:

1.我最开始想到了要两次DP,先算一个是否是回文数的dp数组,再算所求的DP。
但第二个DP数组我用的二维数组,然后就变成了O(N^3)时间。因为对于其中每个元素都要从左边界遍历到右边界进行分割,没有想到可以利用第一个DP中的数据。
代码是对的,自己机器跑了,但AC不了,第26个用例超时:

超时的代码!:

 class Solution:
def minCut(self, s: str) -> int:
#先算一个dp数组记录是否是回文数
#dp[i][j]记录s[i,j]闭区间是否是回文数
l=len(s)
if not s:
return 0
dp=[[0 for i in range(l)] for j in range(l)]
for i in range(l):
dp[i][i]=1 #一个元素的一定是回文数,递推起始条件
for i in range(l-1):
if s[i]==s[i+1]:
dp[i][i+1]=1 #两个相邻元素的若值相同,也为回文数
for step in range(2,l):
i=0
while i+step<l:
j=i+step #j为右边界,考察s[i,j]是否是回文数
#矩阵的右上半部,满足i<=j才有意义
dp[i][j]=int(dp[i+1][j-1] and s[i]==s[j])
#当前字符串为回文数的条件:两边界截掉是回文数
i+=1
#回文数dp数组建立好,考虑对于s[i,j]字符串的最少分割次数f(i,j),
#若当前字符串为回文数即dp[i][j]==1则分割次数f(i,j)为0,不用割,
#否则可能的切割位置为i+1到j-1,假设切割位置为k(i<k<j),
#还需要知道f(i,k),f(k+1,j),故还需要一个求最少分割次数的dp数组
dp2=[[float('inf') for i in range(l)] for j in range(l)]
for i in range(l):
dp2[i][i]=0 #单个字符串不用割,其他元素初始化为无穷大
for step in range(1,l): #对[i,i+step]闭区间考察,i取0时,0+step应该小于l
i=0
while i+step<l:
if dp[i][i+step]==1: #若s[i,i+step]已是回文
dp2[i][i+step]=0
else:
#若s[i,i+step]不是回文,则一定要切,下面开始切
cur_min=float('inf')
for cut in range(i,i+step):
#找割数最小的割法
cur_min=min(cur_min,dp2[i][cut]+dp2[cut+1][i+step]+1)
dp2[i][i+step]=cur_min
i+=1
# print(dp)
# print(dp2)
return dp2[0][l-1]

2.正确代码:
第一个dp数组一样,必须是二维的。第二个dp数组一维的,dp2[i]表示从i开始到末尾的字符串的最小分割数,对于每个dp[i],在i+1到n-1找分割点k就完事了,i到k为回文串通过第一个DP数组查询,O(1) ,剩下的k到n-1是之前算好的,所以第二个DP数组要从右往左算,因为右边界不动。总体O(N^2)复杂度。

c++:

 class Solution {
public:
#define inf INT_MAX
int minCut(string s) {
int n=s.size();
vector<vector<bool>> is_huiwen(n,vector<bool>(n,false));
for(int i=0;i<n;++i){is_huiwen[i][i]=true;}
for(int i=0;i<n-1;++i){is_huiwen[i][i+1]=(s[i]==s[i+1]?true:false);}
//下往上,左往右算dp
for(int i=n-3;i>=0;--i){
for(int j=i+2;j<n;++j){
is_huiwen[i][j]=(s[i]==s[j] and is_huiwen[i+1][j-1])?true:false;
}
}
vector<int> dp(n,inf);//dp[i]表示s截止到i最小分割次数(inf表示没法分割)
for(int i=0;i<n;++i){
if(is_huiwen[0][i]){
dp[i]=0;
continue;
}
for(int cut=1;cut<=i;++cut){
if(is_huiwen[cut][i] and dp[cut-1]!=inf){
dp[i]=min(dp[i],dp[cut-1]+1);
}
}
}
return dp[n-1];
}
};

python:

 class Solution:
def minCut(self, s: str) -> int:
l=len(s) #先算一个dp数组记录是否是回文,dp[i][j]记录s[i,j]闭区间是否是回文数
if not l:
return 0
dp=[[0 for i in range(l)] for j in range(l)]
for i in range(l-1,-1,-1): #从下往上,从右往左算
for j in range(l-1,i-1,-1):
if s[i]==s[j]:
dp[i][j]=1 if j-i<2 else dp[i+1][j-1]
dp2=[float('inf') for i in range(l)] #dp2[i]表示从i开始到末尾字符串的最小分割数
for i in range(l-1,-1,-1):
if dp[i][l-1]: #当前字符串是回文数
dp2[i]=0
else:
_min=float('inf')
for cut in range(i,l-1): #不同割点位置
if dp[i][cut]==1:
_min=min(dp2[cut+1]+1,_min)
dp2[i]=_min
print(dp2)
return dp2[0]

132. 分割回文串 II的更多相关文章

  1. Java实现 LeetCode 132 分割回文串 II(二)

    132. 分割回文串 II 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回符合要求的最少分割次数. 示例: 输入: "aab" 输出: 1 解释: 进行一 ...

  2. Leetcode 132.分割回文串II

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

  3. [LeetCode] 132. 分割回文串 II

    题目链接 : https://leetcode-cn.com/problems/palindrome-partitioning-ii/ 题目描述: 给定一个字符串 s,将 s 分割成一些子串,使每个子 ...

  4. LeetCode 132. 分割回文串 II(Palindrome Partitioning II)

    题目描述 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回符合要求的最少分割次数. 示例: 输入: "aab" 输出: 1 解释: 进行一次分割就可将 s ...

  5. 132 Palindrome Partitioning II 分割回文串 II

    给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串.返回 s 符合要求的的最少分割次数.例如,给出 s = "aab",返回 1 因为进行一次分割可以将字符串 s 分 ...

  6. 分割回文串 II · Palindrome Partitioning II

    [抄题]: 给定一个字符串s,将s分割成一些子串,使每个子串都是回文. 返回s符合要求的的最少分割次数. [思维问题]: 不知道要用预处理字符串降低复杂度 [一句话思路]: 先把预处理获得s中回文串的 ...

  7. [Swift]LeetCode132. 分割回文串 II | Palindrome Partitioning II

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  8. LeetCode 131. 分割回文串(Palindrome Partitioning)

    131. 分割回文串 131. Palindrome Partitioning 题目描述 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. LeetC ...

  9. 分割回文串 · Palindrome Partitioning

    [抄题]: 给定一个字符串s,将s分割成一些子串,使每个子串都是回文串. 返回s所有可能的回文串分割方案. 给出 s = "aab",返回 [ ["aa", & ...

随机推荐

  1. [CF1311F] Moving Points - 树状数组

    Solution 按 \(x\) 关键字升序排序,依次枚举每个点 考虑对任意 \(x_j < x_i\),那么当 \(v_j \leq v_i\) 时,它们不会相交,且 \(dis\) 就是它们 ...

  2. 一、JVM之类加载器

    一.什么是JVM 先来看下百度百科的解释: JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,JVM 是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计 ...

  3. Spark学习之路 (二十三)SparkStreaming的官方文档[转]

    SparkCore.SparkSQL和SparkStreaming的类似之处 SparkStreaming的运行流程 1.我们在集群中的其中一台机器上提交我们的Application Jar,然后就会 ...

  4. 关于f(x)

    有时 z = x + y 有时 0 = x + y 有时单独用f(x) 有时 z = f(x) 很容易分不清. 从集合角度,将f(x)看成映射 即从A集合到B集合的对应关系 这样f(x)可以单独使用, ...

  5. ovs安装教程

    原文链接:https://www.cnblogs.com/goldsunshine/p/10331606.html Open vSwitch系列之二 安装指定版本ovs   Open vSwitch系 ...

  6. Centos7 同时运行PHP5.2和PHP7.1配置

    工作环境一直都是lnmp,其中PHP已经升级到7.1版本了.突然有份代码需要运行在PHP5.2上.但是之前的环境还是需要的,所以需要在centos中再安装PHP5.2. 0.之前的php7安装在/us ...

  7. 树莓派使用Python使用PiCamera录制视频

    个人博客 地址:https://www.wenhaofan.com/article/20190430144020 代码 在树莓派环境下官方提供了乐酷 PiCamera 让我们可以很方便的操作树莓派连接 ...

  8. PCI Express

    1.1课题研究背景 在目前高速发展的计算机平台上,应用软件的开发越来越依赖于硬件平台,尤其是随着大数据.云计算的提出,人们对计算机在各个领域的性能有更高的需求.日常生活中的视频和图像信息包含大量的数据 ...

  9. pytest+requests+Python3.7+yaml+Allure+Jenkins+docker实现接口自动化测试

    接口自动化测试框架(用例自动生成) 项目说明 本框架是一套基于pytest+requests+Python3.7+yaml+Allure+Jenkins+docker而设计的数据驱动接口自动化测试框架 ...

  10. 我的第一个原生Web Components——滑块(SingleSlider)

    写着写着,就会跑偏,没错又走上了一个岔道……就是不知道这条岔道以后会不会越来越宽,有的说他是未来,有的说…… 这里不知道,也不做什么评断.减少一些重复性的工作,提高开发效率这是最根本的.说白了就是偷懒 ...