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

 

posted @ 2018-07-27 21:01  siren27  阅读(128)  评论(0编辑  收藏  举报