开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第26天,点击查看活动详情
回文字串
给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
示例 1:
输入: s = "abc"
输出: 3
解释: 三个回文子串: "a", "b", "c"
示例 2:
输入: s = "aaa"
输出: 6
解释: 6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
提示:
1 <= s.length <= 1000s由小写英文字母组成
思路
该题目可作为最长回文字串的基础版,同样是需要求得回文字串,中心思想在于由一个中心轴开始向两边扩展,判断两个边界的字符是否相等,由于中心元素是确定的并且相等的,故不需要重复的判断中心字符串的回文性,只需要关注边界字符,提高了检索的效率。
具体而言,我们需要找到每个字符串的中心位置,当字符串长度为偶数个时,字符串是两两对称的,而字符串长度为奇数个时,字符串中心的字符可以为任意字符,其两侧的字符两两对称。
第一层遍历所有中心字符的情况,第二层由中心字符向两侧扩展,对于每个中心字符,需要考虑到字符串长度为奇数和偶数的情况。
题解
class Solution {
public int countSubstrings(String s) {
int cnt = 0;
for(int i = 0; i < s.length(); i++) {
int left = i, right = i;
cnt += getCnt(s, i, i) + getCnt(s, i, i + 1);
}
return cnt;
}
private int getCnt(String s, int left, int right) {
int cnt = 0;
while(left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
cnt++;
}
return cnt;
}
}