【leetcode】132.(Hard) Palindrome Patitioning II

解题思路:

这道题用到了DP,以"gacbbcak"为例进行说明。

首先创建boolean二维数组:

第i行第j列表示字符串第i位到第j位字符是否构成回文串;
例如这个二维数组第3行第5列表示字符串的从第3位到第5位子串,"bbc"是否构成回文串,结果是flase;
左下三角由于i大于j构不成子串所以是空的(比如从原字符串从左到右第5位到第3位是构不成的子串):
在这里插入图片描述
填表的顺序为:
在这里插入图片描述
填表的原则为:

char[i] == char[j]&&i == j时 构成回文串,为true

例如对于"gacbbcak",i=j=2时,char[i]=char[j]=‘c’,表示的是子字符串"c",是回文的

char[i] == char[j]&&j-i==1时 构成回文串,为true

例如对于"gacbbcak",i=3,j=4时,表示子串"bb",是回文的


char[i] == char[j]&&j-i == 2时 构成回文串,为true

例如对于"aba"字符串来说,当i=0,j=2时,是回文的

char[i] == char[j]&&dp[i+1][j-1]时 构成回文串,为true

例如假设有下面的字符串:
在这里插入图片描述
当i=2,j=8时,char[i]==char[j]
同时只要dp[i+1][j-1]即中间那个红框中的部分是回文的,那从第2位到第8位就是回文的。
这里dp[i+1][j-1]是个布尔数值,表示字符串中从i+1位到j-1位是否是回文的


综上,这个二维数组中的元素dp[i][i]为true的条件是:

if(s.charAt(i)==s.charAt(j)&&((j-i<=2)||dp[i+1][j-1]))	
	dp[i][j]=true;

上面这句代码就包含了上面所有的填表原则。


计算minCut值:

对字符串"gacbbcak"填表:

gacbbcak
g10000000
a1000000
c100100
b11000
b1000
c100
a10
k1

然后创建一个数组cnt[],用于保存字符串从第i位到最后一位有多少个回文串,i取值0~字符串长度
例如cnt[7]表示从字符串第7位到最后一位,即子串"k"有1个回文串;
cnt[3]表示子串"bbcak"中有多少个子回文串,有4个(“bb”,“c”,“a”,“k”);
计算的原则为:

cnt[i]=Math.min(1+cnt[j+1],cnt[i]);

例如:
在这里插入图片描述
在计算cnt[2]时,圆圈1中的dp[2][5]为true,说明方框2中的子串"cbbc"是回文的,那我直接调用cnt[6]即方框4中的数字来看一下剩下的"ak"中有多少个回文串即可。
可以看到cnt[6]=2, 即"ak"中有两个回文串(“a"和"k”)
所以cnt[2]=1+cnt[6]=3,即子串"cbbcak"中有3个回文串(“cbbc”, “a"和"k”)


提交代码:

class Solution{
	public int minCut(String s) {
		boolean[][] dp=new boolean[s.length()][s.length()];
		
		for(int i=s.length()-1;i>=0;i--) 
			for(int j=i;j<s.length();j++) 
				if(s.charAt(i)==s.charAt(j)&&((j-i<=2)||dp[i+1][j-1]))	dp[i][j]=true;
			
		int[] cnt=new int[s.length()+1];
		for(int i=s.length()-1;i>=0;i--) {
			cnt[i]=Integer.MAX_VALUE;
			for(int j=i;j<s.length();j++) {
				if(dp[i][j])
					cnt[i]=Math.min(1+cnt[j+1],cnt[i]);
			}
		}
		
		return cnt[0]-1;
	}
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值