LeetCode最长回文子串

最长回文子串

题目要求

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

思路

寻找最长回文子串,也就是求一个字符串中的最优解。谈到最优解,首先应该想到动态规划算法。也就是把一个问题分成若干独立小问题,前一步问题为后一步问题做铺垫,并且将每一步的结果储存起来。这样,这个问题就成为了寻找最短回文子串,并将其一步步扩充为最长回文子串。

  • 使用动态规划,用二维数组去存储每一步的结果。

  • 将字串倒置,找出倒置子串与源子串重合的部分。

  • 判定重合的部分是否为回文串。

    反例:
    aacbecaa 并不包含回文串,将其倒置之后,aacebcaa, aac和倒置后caa部分相重合,所以必须重新判断它是否为一个回文子串。

    例子:以 abacd为例,
    第一步:

!)
将 cell [i] [j] 行列相等的部分单元格内数字置为1.
第二步:
在这里插入图片描述
到了第二个 cell [i] [j]行列相等的时候,查看cell [i-1] [j-1] 内单元格数字是否为 1 ,为1的话进行累加。
第三步:
在这里插入图片描述
第三步同上,继续查看cell [i-1] [j-1]单元格,将单元格内的数字累加值 cell [i] [j]。

解释:
累加部分就代表了动态规划中的保存每一步的结果,并供下一步使用,加到最后,我们只需要关注矩阵中的最大值和 列数 J 的值。 J 对应着原字符串中的回文串最后一位的索引,矩阵最大值代表回文串的长度。至此,就可以得到最长的回文串。

代码

public String longestPalindrome(String s) {
		//存贮每一步运行结果
       int[][] cell = new int[s.length()][s.length()];
       int len = 0;
       int maxEnd = 0;
       String strReverse = new StringBuffer(s).reverse().toString();
       for (int i = 0; i < s.length(); i++) {
           for (int j = 0; j < strReverse.length(); j++) {
               if (strReverse.charAt(i) == s.charAt(j)) {
                   if (i == 0 || j == 0)
                       cell[i][j] = 1;
                   else {
                       cell[i][j] = cell[i - 1][j - 1] + 1;
                   }
                   if (len < cell[i][j] ) {

                       //效验是否为回文串
                       if (s.substring(j + 1 - cell[i][j], j + 1).equals(new StringBuffer(s.substring(j + 1 - cell[i][j], j + 1)).reverse().toString())) {
                           len = cell[i][j];
                           // J 的下标从零开始
                           maxEnd  = j + 1;
                       }

                   }
               } else {
                   cell[i][j] = 0;
               }
           }
       }

       return s.substring(maxEnd  - len, maxEnd );
   }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值