美文网首页
每日一题:5. 最长回文子串

每日一题:5. 最长回文子串

作者: 北漂三十年 | 来源:发表于2023-03-04 00:59 被阅读0次

package com.ljp.test.leetcode;

/**

  • <h2>5. 最长回文子串</h2>

  • <p>

  • 给你一个字符串 s,找到 s 中最长的回文子串。

  • <p>

  • 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

  • <p>

  • <p>

  • 示例 1:

  • <p>

  • 输入:s = "babad"

  • 输出:"bab"

  • 解释:"aba" 同样是符合题意的答案。

  • 示例 2:

  • <p>

  • 输入:s = "cbbd"

  • 输出:"bb"

  • <p>

  • 提示:

  • <p>

  • 1 <= s.length <= 1000

  • s 仅由数字和英文字母组成

  • <p>

  • 来源:力扣(LeetCode)

  • 链接:<a href="https://leetcode.cn/problems/longest-palindromic-substring">5. 最长回文子串</a>

  • 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
    */
    public class Number0005 {

    public static void main(String[] args) {
    String s1 = "babad";
    String s2 = "cbbd";
    String s3 = "abcddcbaefghjk";
    String s4 = "a";
    String s5 = "abcd";
    System.out.println(DynamicPlanning.longestPalindromicSubstring(s1));
    System.out.println(DynamicPlanning.longestPalindromicSubstring(s2));
    System.out.println(DynamicPlanning.longestPalindromicSubstring(s3));
    System.out.println(DynamicPlanning.longestPalindromicSubstring(s4));
    System.out.println(DynamicPlanning.longestPalindromicSubstring(s5));
    System.out.println("---------------------------------------------");
    System.out.println(ExpandAroundCenter.longestPalindromicSubstring(s1));
    System.out.println(ExpandAroundCenter.longestPalindromicSubstring(s2));
    System.out.println(ExpandAroundCenter.longestPalindromicSubstring(s3));
    System.out.println(ExpandAroundCenter.longestPalindromicSubstring(s4));
    System.out.println(ExpandAroundCenter.longestPalindromicSubstring(s5));
    }

    /**

    • 动态规划

    • 三大步骤:

    • 1、定义数组元素的含义:result[i][j]=true,表示下标i到下标j是当前字符串的回文子串

    • 2、找出数组元素之间的关系式:result[i+1][j-1]=true and chars[i]==char[j]=true,则result[i][j]=true

    • 3、找出初始值:result[i][i]=true chars[i]==char[i+1],则result[i][i+1]=true chars[i]==char[i+2],则result[i][i+2]=true
      */
      private static class DynamicPlanning {

      public static String longestPalindromicSubstring(String s) {
      int length = s.length();
      if (length == 1) return s;
      boolean[][] result = new boolean[length][length];
      // 最长回文字符串为1
      for (int i = 0; i < length; i++) {
      result[i][i] = true;
      }
      char[] chars = s.toCharArray();
      int begin = 0, maxLength = 1;
      // 最长回文字符串为2到length
      for (int n = 2; n < length; n++) {
      for (int i = 0; i < length; i++) {
      int j = i + n - 1;
      if (j >= length) {
      break;
      }
      if (chars[i] != chars[j]) {
      result[i][j] = false;
      } else {
      // 当子字符串长度为2和3时,必是子回文字符串
      if (j - i < 3) {
      result[i][j] = true;
      } else {
      result[i][j] = result[i + 1][j - 1];
      }
      }
      if (result[i][j] && j - i + 1 > maxLength) {
      begin = i;
      maxLength = j - i + 1;
      }
      }
      }
      return s.substring(begin, begin + maxLength);
      }

    }

    /**

    • 中心扩展算法
      */
      private static class ExpandAroundCenter {

      public static String longestPalindromicSubstring(String s) {
      int length = s.length();
      if (length == 1) return s;
      int begin = 0, maxLength = 1;
      for (int i = 0; i < length; i++) {
      int l1 = expandAroundCenter(s, i, i);
      int l2 = expandAroundCenter(s, i, i + 1);
      int tempMaxLength = Math.max(l1, l2);
      if (maxLength < tempMaxLength) {
      maxLength = tempMaxLength;
      begin = i - (maxLength - 1) / 2;
      }
      }
      return s.substring(begin, begin + maxLength);
      }

      private static int expandAroundCenter(String s, int left, int right) {
      while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
      left--;
      right++;
      }
      // left多减了1,right多加了1.所以length=right-left+1-2=right-left-1
      return right - left - 1;
      }

    }

}

相关文章

网友评论

      本文标题:每日一题:5. 最长回文子串

      本文链接:https://www.haomeiwen.com/subject/mamcaltx.html