zoukankan      html  css  js  c++  java
  • [Leetcode]5. 最长回文子串

    题目描述

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

    • 示例 1:
    输入:s = "babad"
    输出:"bab"
    解释:"aba" 同样是符合题意的答案。
    
    • 示例 2:
    输入:s = "cbbd"
    输出:"bb"
    
    • 示例 3:
    输入:s = "a"
    输出:"a"
    
    • 示例 4:
    输入:s = "ac"
    输出:"a"
    

    第一种解法(暴力解法)

    class Solution {
    
      //查询指定字符串最长子串
      public String longestPalindrome(String s) {
        int maxLen = 0;
        int left = 0;
        //babad
        for (int i = 0; i < s.length(); i++) {
          for (int j = i; j < s.length(); j++) {
            String temp = s.substring(i, j + 1);
            if ((j - i + 1) > maxLen && isPalindrome(temp)) {
              maxLen = j - i + 1;
              left = i;
            }
          }
        }
        return s.substring(left, maxLen + left);
      }
    
      private boolean isPalindrome(String source) {
        char[] array = source.toCharArray();
        int left = 0;
        int right = array.length - 1;
        while (left < right) {
          if (array[left] != array[right]) {
            return false;
          }
          left++;
          right--;
        }
        return true;
      }
    
      public static void main(String[] args) {
        System.out.println(new Solution().longestPalindrome("a"));
      }
    }
    

    找出所有子串,判断每一个子串是否是回文串。时间复杂度为 O(N^3),超出时间限制。

    第二种解法(中心扩展)

    class Solution2 {
    
      //查询指定字符串最长子串
      public String longestPalindrome(String s) {
        //babad
        int[] res = new int[2];
        for (int i = 0; i < s.length(); i++) {
          searchPalindrome(s, i, i, res);
          searchPalindrome(s, i, i + 1, res);
        }
        return s.substring(res[0], res[0] + res[1]);
      }
    
      private void searchPalindrome(String s, int start, int end, int[] res) {
        while (start >= 0 && end < s.length()) {
          if (s.charAt(start) != s.charAt(end)) {
            break;
          }
          start--;
          end++;
        }
        if (end - start - 1 > res[1]) {
          res[0] = start + 1;
          res[1] = end - start - 1;
        }
      }
    
      public static void main(String[] args) {
        System.out.println(new Solution2().longestPalindrome("a"));
      }
    }
    

    从一个中心向两边扩展,直到可以判断出不是回文串,例如 habcdcbag ,以d为中心扩展,得到的回文串为 abcdcba,从所有回文串中选出最大的。时间复杂度为 O(N^2),可以通过AC。

    第三种解法(动态规划)

    class Solution3 {
    
      //查询指定字符串最长子串
      public String longestPalindrome(String s) {
        int len = s.length();
        if (len < 2) {
          return s;
        }
        int maxLen = 1;
        int start = 0;
        //memo[j][i]表示下标j-i之间为回文串
        boolean[][] memo = new boolean[len][len];
        for (int i = 0; i < len; i++) {
          memo[i][i] = true;
        }
        for (int i = 0; i < len; i++) {
          for (int j = 0; j < i; j++) {
            if (s.charAt(i) != s.charAt(j)) {
              memo[j][i] = false;
            } else {
              //[0,2]
              if (i - j < 3) {
                memo[j][i] = true;
              } else {
                memo[j][i] = memo[j + 1][i - 1];
              }
            }
            if (memo[j][i] && i - j + 1 > maxLen) {
              maxLen = i - j + 1;
              start = j;
            }
          }
        }
        return s.substring(start, start + maxLen);
      }
    
      public static void main(String[] args) {
        System.out.println(new Solution3().longestPalindrome("abcbads"));
      }
    }
    

    如果一个子串的头尾不相同,一定不是回文串,
    如果相等,判断去除头尾之后的子串是否为回文串。
    以 habcdcbag 字符串为例,habcdcba 不是回文子串,abcdcba 是回文子串。时间复杂度为 O(N^2),可以通过AC。

  • 相关阅读:
    科技爱好者周刊(第 175 期):知识广度 vs 知识深度
    科技爱好者周刊(第 173 期):网络收音机的设计
    Telegra.ph | 简洁的文章发布平台
    前端规范
    Vue入门笔记三(Vuex)
    Vue入门笔记二
    Vue入门笔记一
    多点商城小程序案例笔记一
    sublime text 笔记
    windows下安装SASS
  • 原文地址:https://www.cnblogs.com/strongmore/p/14449797.html
Copyright © 2011-2022 走看看