【算法】字符串中的回文子串

这一题 是LeetCode 的第五道题,链接如下:
5. 最长回文子串

常见的解法

动态规划

定义一个二维数组 boolean[][]boolean[i][j] 表示的是从 i 到 j 是不是回文串,其中 i 和 j 分为 以下几种情况:

  • “aaa”,“aba”:这两种都是一个回文串
  • “eabce”:此时虽然最后一个和第一个是相等的,但是 i + 1 和 j - 1 却不是相等的,因此不是回文串。

思路一:

从左到右一直遍历

for(int right = 0; right < len; right++){
     for(int left = 0; left < right; left++){
         if(s.charAt(left) != s.charAt(right)){
             continue;
         }
         if(left == right){
             dp[left][right] = true;
         } else if(right - left <= 2){
             dp[left][right] = true;
             
         } else {
             dp[left][right] = dp[left + 1][right - 1];
         }
         if(dp[left][right] && right - left + 1 > maxLen){
             start = left;
             maxLen = right - left + 1;
         }
     }
 }

此种方法,只需要定位到 start 和 maxLen,就可以得到最终的最长的回文子串

思路二

定长循环,从左边开始,依次间隔 N 个字符进行判断,因为一个字符肯定是回文,所以最短的是从 2 开始,最长是整个字符串。

for(int step = 2; step <= charArray.length; step++){
     for(int left = 0; left < charArray.length; left++){
         int right = left + step - 1;
         if(right >= charArray.length){
             break;
         }
         if(charArray[left] == charArray[right]){
             if(right - left < 3){
                 dp[left][right] = true;
             } else {
                 dp[left][right] = dp[left + 1][right - 1];
             }
         } else {
             dp[left][right] = false;
         }
         if(dp[left][right] && right - left + 1 > maxLen){
             start = left;
             maxLen = right - left +1;
         }
     }
 }

两种方法最后都是调用 s.substring(start,start + maxLen) 得到最长的回文。

中心扩展法

中心扩展法的思想就是遍历一遍,然后从当前下标向两边扩散,需要注意的是扩散的需要区分两种情况

a*a

这种就简单很多,left++,right–即可

baab

如果此时的下标是 1,那么left = 1,right 就需要 +1 开始遍历了

int len1 = expandAroundCenter(s, i, i);
int len2 = expandAroundCenter(s, i, i + 1);
int len = Math.max(len1, len2);

Manacher 算法

有点复杂。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值