剑指 Offer II 020. 回文子字符串的个数

565 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

一、题目描述:

给定一个字符串 s ,请计算这个字符串中有多少个回文子字符串。

具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

 

示例 1:

输入:s = "abc" 输出:3 解释:三个回文子串: "a", "b", "c" 示例 2:

输入:s = "aaa" 输出:6 解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"  

提示:

1 <= s.length <= 1000 s 由小写英文字母组成  

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/a7…

二、思路分析:

  • 本题的解题思路就是换一个方向从字符串的中心开始向两端延伸

  • 如果存在一个长度为m的回文子字符串,则向该回文的两端延伸一个字符,判断回文前后的字符是否相同,如果相同就找到一个长度为m+2的回文子字符串

  • 回文的长度既可以是奇数,也可以是偶数;长度为奇数的回文的对称中心只有一个字符;长度为偶数的回文的对称中心只有两个字符

具体做法: 依次遍历每个节点,找到当前节点对应的子串的中心点,依次向外拓展,需注意的是当前子串的长度可能是奇数也可能是偶数, 对应的,当前子串中心可以是一个节点,也可以是两个节点, 遍历节点0时,其子串中心为(0,0) 遍历节点1时,其子串中心为(0,1)、(1,1) 遍历节点2时,其子串中心为(1,1)、(1,2)、(2,2) 遍历节点3时,其子串中心为(1,2)、(2,2)、(2,3)、(3,3)

三、AC 代码:

class Solution 
{
    public int n;

    public int countSubstrings(String s) 
    {
        this.n = s.length();

        int res = 0;
        for (int i = 0; i < n; i ++)
        {
            int odd = get_max_len(s, i, i);
            int even = get_max_len(s, i, i + 1);
            res += odd;
            res += even;
        }
        return res;
    }

    public int get_max_len(String s, int l, int r)
    {
        int cnt = 0;
        while (0 <= l && r < n && s.charAt(l) == s.charAt(r))
        {
            cnt ++;
            l --;
            r ++;
        }
        return cnt;
    }
}

四、总结:

写题解不易,若对你有帮助,点赞评论再走吧。ヽ(✿゚▽゚)ノ,如有不足,请大家斧正。