【精】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".

Note:

  1. The input string length won't exceed 1000.

题意

给定一个字符串,你的任务是计算在该字符串中有多少个回文子串。

子串如果有不同的起始索引或者结束索引,那么便可以认为是不同的,即使他们包含着相同的字符。

(例子:见以上英文)

分析及解答

(1)什么叫做回文串?(见百度百科:回文串)

(2)回文串具有什么性质?

  • 【特性】正读、反读都是一样的字符串。
  • 【另一种说法】左右对称的串。(后面将会用到这个性质进行算法设计)


(3)利用性质寻找算法


前面提到了回文串具有对称的性质,那么我们应该如何利用这个性质呢?让我们观察一下字符串实例(观察图1,图2),我们能够发现:

  • 对称轴】回文串都有某个对称轴(奇数个字符的串对称轴为最中间的字符。偶数不同,偶数的对称轴可以看做两个(如图2)).
  • 回文串的规律当在回文串两端各加入两个相同的字符的时候,形成的新字符仍旧是回文串。(关键
  • 构造回文的初始】我们可以从一个字符,或者两个相同字符开始,运用以上两个规律开始构造回文(不断同时往两边加相同的字符)。

图1:(回文串,奇数个字符)

【精】leetcode - 647. Palindromic Substrings【动态规划 + 回文 + 对称性】_第1张图片

图2:(回文串,偶数个字符)

【精】leetcode - 647. Palindromic Substrings【动态规划 + 回文 + 对称性】_第2张图片

解法1:(简洁 + 代码技巧)

public class Solution {
    int count  = 0;
    public int countSubstrings(String s) {
        for(int i = 0;i=0 && right < s.length() && s.charAt(left) == s.charAt(right)){
            count++;
            left--;
            right++;
        }

解法2:(我的做法,有些冗余,下标处不太让人用于理解)
  • 【循环语句的使用】像解法1一样,如果将for循环变成while循环,能够节省不少代码量,同时也容易让人读懂。

public class Solution {
    public int countSubstrings(String s) {
       
    	int length = s.length();
        int[][] paliSign = new int[length][length];
        int sum = 0;
        
        sum += length;
        for(int i =0;i < length;i++){
        	paliSign[i][i] = 1;
        	if(i != length -1 && s.charAt(i) == s.charAt(i+1)){
        		paliSign[i][i+1] = 1;
        		sum += 1;
        	}
        }
                
        for(int gap =0; gap <= length-2;gap++){
        	for(int i = 1; i <= length-gap-2; i++){
        		if(paliSign[i][i+gap] == 1 && s.charAt(i-1)== s.charAt(i+gap+1)){
        			paliSign[i-1][i+gap+1]=1;
        			sum += 1;
        		}
        	}
        }

        return sum;
    
    }
}





你可能感兴趣的:(算法练手)