我的LeetCode代码仓:https://github.com/617076674/LeetCode
原题链接:https://leetcode-cn.com/problems/palindromic-substrings/
题目描述:
知识点:动态规划
思路一:暴力破解法
时间复杂度是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解题报告:
思路二:动态规划
状态定义:
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解题报告:
思路三:分别计算长度为奇数和偶数的回文子串数量
对于奇数回文串,从某个字符向两边扩张。
对于偶数回文串,从某两个字符向两边扩张。
时间复杂度在最差情况下是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解题报告: