LeetCode 647.Palindromic Substrings

先看题目描述:

 Given a string, your task is to count how many palindromic substrings in this string.

The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.

Example 1.

Input: "abc"
Output: 3
Explanation: Three palindromic strings: "a", "b", "c".

Example 2.

Input: "aaa"
Output: 6
Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".

 

题意很简单,是说:给出一个字符串,要求求出这个字符串,所有回文子串的数目。包括单个字符的子串。

解题思路:

看到这题的同时我们就应该清楚这是一道动态规划的问题。它满足了动态规划的两个基本特征:即优化子结构和子问题重叠性。

子问题重叠性可以很容易地看出,这里就不过多阐述了,如果有困难可以画出递归树,就能容易地发现这一点了。

 

下面确定它的优化子结构:

对一个字符串,设起始位置为i,结束位置为j , 想要求它的回文子串数目,即求countPalindromic(i , j)。现在对它进行切分。

我们可能很快想到求,countPalindromic(i, j)= countPalindromic(i ,j - 1)+ countPalindromic(i + 1, j),但是很容易证伪,为什么呢?

因为我们重复计算了从 i + 1到 j - 1 这一部分的回文子字符串。无论是 countPalindromic(i ,j - 1)还是 countPalindromic(i + 1, j),两者都已经

计算了 countPalindromic(i  + 1,j - 1),所以我们要减去一个。

所以优化子结构应该为:countPalindromic(i, j)= countPalindromic(i ,j - 1)+ countPalindromic(i + 1, j)-  countPalindromic(i  + 1,j - 1)

给出优化子结构下一步不难计算了。

要注意每一步还要检查整个字符串是否为回文字符串。

使用java比较判断回文字符串,比较简单。可以使用stringbuilder中的reverse方法,就会使得判断比较容易。

下面给出伪代码:

pseudo-code:
Input: str ,a string Output: num , the number of palindromic substrings of str countPali(str) n
<- str.length let Pali[0 1 ..n, 0 1..n) be a new table for i <- 0 to n: Pali[i][i] <- 1 //init string with a single char has one palindromic substring for i <- 0 to n - 1 for j <- (n - 1) to i + 1: if(str.sub(j - i + 1, j).isPali): pali[j - i - 1][j] = pali[j - i][j] + pali[j - i - 1][j - 1] - pali[j - i][j - 1] + 1 else: pali[j - i - 1][j] = pali[j - i][j] + pali[j - i - 1][j - 1] - pali[j - i][j - 1] return pali[0][n]

 

java实现:https://github.com/1163710128/LeetCode/blob/master/LeetCode647PalindromicSubstrings.java

 

转载于:https://www.cnblogs.com/siren27/p/9379626.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值