【leetcode】647.回文子串
距离上次更新本文已经过去了 268 天,文章部分内容可能已经过时,请注意甄别。
leetcode刷题笔记-647.回文子串
题目
给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
plaintext
1 | 示例 1: |
提示:
plaintext
1 | 1 <= s.length <= 1000 |
思路一:双指针法
我们可以遍历整个字符串,用双指针法从当前下标开始扩张寻找回文子串。找寻相同的字符,如果找到了,则将结果集加一(回文子串个数)。
这里需要注意的是,回文子串有两种情况,一种是奇数长度,我们从中间位置开始扩张就OK了,另外一种是偶数长度,我们必须从中间两位开始扩张。
这个思路比较好理解,所以直接上代码。主要还是注意奇数和偶数这两种不同的回文子串长度。偶数情况可以从(i-1,i)
开始找,也可以从(i,i+1)
开始找,最终结果都是等价的。
cpp
1 | class Solution { |
思路二:动态规划
动态规划的思路就在516最长回文子序列题目里面接触过了。
动态规划的思路主要还是在于回文子串的特性是只需要判断首末两个字符是否相同。如果相同,再根据之前判断的结果,看这两个字符中间的部分是否回文,就能得出整体是否回文。
定义二维bool数组dp,长和宽都是字符串的长度;dp[i][j]
的含义是i和j之间的子串是否为回文子串。
此时递推就只有s[i]==s[j]
的情况需要进行操作,分为三种长度
- 长度为1,一个字符是回文;
- 长度为2,两个字符相同,比如
aa
,也是回文; - 长度大于2,可能是奇数回文也可能是偶数回文子串,判断
dp[i+1][j-1]
是否为true。
根据这个递推关系,i和j的遍历顺序也需要进行修改,首先j肯定大于i,所以j是从i开始正序遍历的(因为j依赖于j-1);而i依赖于i+1,所以i是从最后一个字符开始倒叙遍历的。
初始化的时候,只需要初始化矩阵中i和j相等的部分,相当于一个字符,是回文子串。
完整代码如下
cpp
1 | class Solution { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 慕雪的寒舍!
评论
Artalk Error
Retry
Retry