[路飞]_每天刷leetcode_05(回文子串)

277 阅读3分钟

这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战

回文子串

今天我们来看一道关于字符串的题目,回文子串。在这里我们先明确什么是回文串(回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串)。这个算法题非常有意思,对我来说是一道有点难度的题,大家一起来看一看。

LeetCode原题传送门647. 回文子串

题目

给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。

回文字符串 是正着读和倒过来读一样的字符串。

子字符串 是字符串中的由连续字符组成的一个序列。

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

Given a string s, return the number of palindromic substrings in it.

A string is a palindrome when it reads the same backward as forward.

A substring is a contiguous sequence of characters within the string.

Example:

Input: s = "abc"
Output: 3
Explanation: Three palindromic strings: "a", "b", "c".

Input: s = "aaa"
Output: 6
Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".


思考线


解题思路

如果要判断一个字符串是不是回文字符串,我们可以先找到这个字符串的回文中心(回文字符串的中心字符),回文中心可能是一个字符也可能是两个字符(根据字符串的奇偶性)。

根据字符串的长度为 1, 回文中心的个数为1。

长度为2, 回文中心的个数为3(左,右,左右)

长度为3,回文中心的个数为5(左,左中,中,右中,右)

......

由此我们可以推断出长度为n的字符串会生成2n-1组回文中心。

假设回文中心为[l,r], 其中l = i/2, r = i/2 + (i%2).(这个假设是个很有灵性的假设)

这样我们只要遍历 0~ 2n-2, 就可以得到所有可能的回文中心,这样就把奇数和偶数的长度两种情况统一起来了。

根据上面的规则,当我们确定子字符串回文中心以后,我们就可以向两边推算,如果相等则是 一个子回文数,若是不相等在此回文中心下,这个字符串已经没有回文子串了。

那么这个问题的代码实现就呼之欲出了

代码实现

var countSubstrings = function(s) {
    const len = s.length
    let ans = 0;
  	for(let i = 0; i < 2 * len - 1; i ++) {
      let l = Math.floor(i/2);
      let r = l + i % 2;
      while(l >=0 && r < len && s[l] === s[r]) {
          ans ++;
          l --;
          r ++;
      }
    }
  	return ans;
};

总结

这个回文子字符串的问题的核心点是

  1. 你要想如何判断字符串是不是回文字符串 ---> 找回文中心。
  2. 如何找到长度为n的字符串的回文中心的通项公式。(重点,整个解法最重要的突破点)
  3. 如何让奇数和偶数的回文中心统一起来。(难点,难以想象出这个点,第一个想出的人肯定体会到了灵光乍现的爽快)

好了这就是今天的刷题内容,我们明天见。