[路飞]-leetcode647. 回文子串

272 阅读1分钟

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

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

我们采用的是 中心扩散法 , 那么什么是 中心扩散 呢?

中心扩散就是以一个或两个字符为起始点向左右两边拼接字符, 直到两边字符不等停止拼接。

中心扩散分单数扩散双数扩散

举个例子:

 // 这里有个字符串 abcbcaabba
 单数扩散指的是以一个字母向左右两边扩散,我们从第四个字符`b`开始单数扩散,
 如果`b`的左右两边相等,我们的字符串就扩散为`cbc`, 发现后面的字符不相等了,所以就得到了`cbc`的回文字串。
 
 双数扩散是指以两个相邻的字母左右扩散,如倒数第二和第三个`bb`开始扩散,发现左右两边相等则扩散为`abba`,继续扩散后,左右两边的字符不相等了停止扩散,得到了回文字串`abba`
 
 按照这个思路可以有如下扩散的函数
 let n = s.length;
 const spread = (l ,r ) =>{ // l r 分别表示向左扩散的索引和右扩散索引
     let count = 0 // 使用count计数
      while(l >= 0 && r < n-1 && s[l]=s[r]){
          l-- //  同时向左向右扩散
          r++ 
          count++
      }
       return count
 }


 接下来我们需要对字符串进行遍历 做单数和双数的中心扩散
 // 
 let sum = 0
 for(let i = 0; i< n; i++){
     sum+= spread(i,i) // 这里我们针对每个字符做单数扩散 传相同的索引
 }
 for(let i =0; i< n-1;i++){
     sum+= spread(i, i+1) // 这里我们对相邻两个字符做双数扩散 n-1为边界的限定
 }
 // 最终返回sum
 return sum

发现leetcode的中等难度的题目也不是很难, 不到是10几行代码就完成了解答。所以一旦知道了解题思路,就能很快做出来。