LeetCode647——回文子串

我的LeetCode代码仓:https://github.com/617076674/LeetCode

原题链接:https://leetcode-cn.com/problems/palindromic-substrings/

题目描述:

LeetCode647——回文子串_第1张图片

知识点:动态规划

思路一:暴力破解法

时间复杂度是O(n ^ 3),其中n为所给字符串的长度。空间复杂度是O(1)。

JAVA代码:

public class Solution {

    public int countSubstrings(String s) {
        int count = 0, len = s.length();
        for (int i = 0; i < len; i++) {
            for (int j = i + 1; j <= len; j++) {
                if (isPalindrom(s.substring(i, j))) {
                    count++;
                }
            }
        }
        return count;
    }

    private boolean isPalindrom(String s) {
        for (int i = 0; i < s.length() / 2; i++) {
            if (s.charAt(i) != s.charAt(s.length() - i - 1)) {
                return false;
            }
        }
        return true;
    }

}

LeetCode解题报告:

LeetCode647——回文子串_第2张图片

思路二:动态规划

状态定义

f(x, y) -------- [x, y]间的子串是否是回文串

状态转移

(1)如果x == y,说明该子串只有一个字符,显然是回文串。

(2)如果x - y == -1,说明该子串只有两个字符,判断是否是回文串就变成了判断这两个字符是否相等。

(3)对于其他情况,当且仅当索引x处的字符和索引y处的字符相等,且[x + 1, y - 1]间的子串是回文串。

时间复杂度和空间复杂度均是O(n ^ 2),其中n为所给字符串的长度。

JAVA代码:

public class Solution {

    public int countSubstrings(String s) {
        int count = 0, len = s.length();
        boolean[][] dp = new boolean[len][len];
        for (int i = 0; i < len; i++) {
            dp[i][i] = true;
            count++;
        }
        for (int i = -1; i > -len ; i--) {
            for (int j = 0; j < len + i; j++) {
                if (s.charAt(j) == s.charAt(j - i)) {
                    if (i == -1 || dp[j + 1][j - i - 1]) {
                        dp[j][j - i] = true;
                        count++;
                    }
                }
            }
        }
        return count;
    }

}

LeetCode解题报告:

LeetCode647——回文子串_第3张图片

思路三:分别计算长度为奇数和偶数的回文子串数量

对于奇数回文串,从某个字符向两边扩张。

对于偶数回文串,从某两个字符向两边扩张。

时间复杂度在最差情况下是O(n ^ 2),其中n为所给字符串的长度。空间复杂度是O(1)。

JAVA代码:

public class Solution {

    private int result = 0;

    public int countSubstrings(String s) {
        for (int i = 0; i < s.length(); i++) {
            countSubstrings(s, i, i);               //回文串长度为奇数
            countSubstrings(s, i, i + 1);     //回文串长度为偶数
        }
        return result;
    }

    private void countSubstrings(String s, int left, int right) {
        while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            left--;
            right++;
            result++;
        }
    }

}

LeetCode解题报告:

LeetCode647——回文子串_第4张图片

 

你可能感兴趣的:(LeetCode题解)