最长回文子串

最长回文子串

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

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

(1)暴力破解

class Solution {
    public String longestPalindrome(String s) {
        //使用暴力破解的方式进行求解
        //首先判断字符串的长度是否是在可以产生回文子串
        //如果该字符串的长度小于2 为 1 或  0  的话则最长回文子串就是本身
        int len = s.length();
        if(len < 2){
            return s;
        }
        //定义right定义的最大长度
        //left控制最小的
        int right = 1;
        int left = 0;
        char[] ArrayList = s.toCharArray();  //java 中类将字符串转换为字符串数组
        //枚举所有长度大于一的字符串

        for(int i = 0; i < len - 1; i++){
            for(int j = i + 1; j < len; j++) {
                if(j - i + 1 > right && huiwen(ArrayList, i, j)) {
                    right = j - i + 1;
                    left = i;

                }
            }
        }
        return s.substring(left, left + right);   //java 常用的类,将字符串转化为子字符串
    }

    //定义一个布尔函数判断数组是否为回文字符串
    //定义一个数组, 左指针右指针
        private boolean huiwen(char[] array, int left, int right){
            //如果满足left < right则证明数组中含有元素 
            while(left < right){
                //判断左下标对应的值 和右下标对应的值相等 则满足回文子串
                //如果想等满足的话left向右移动  right向左移动
                //依次遍历完left - right中的所有数组元素 如果均相等的话则返回true
                if(array[left] != array[right]){
                    return false;
                }
                left++;
                right--;
            }
            return true;
        }

}

(2)中心扩展算法

**利用和动态规划相似的想法,可以得出这个中心扩展的算法 **

需要注意的是,在这个过程中需要考虑好它的几种特殊情况 以及对于下标的把控,控制其不会下标越界

class Solution {
    public String longestPalindrome(String s) {
      //使用中心扩展的方法进行求解
      //先对特殊情况进行判断
      //如果字符串为空或者是字符串的长度小于1 直接返回一个空的字符串
      if(s == null || s.length() < 1) {
          return " ";
      }
      //定义两个控制变量, 一个控制开始,一个控制结束
      int left = 0, right = 0;
      //开始遍历数组中的元素
      for(int i = 0; i < s.length(); i++) {
          //这里要讨论两种情况  分别是字符串为奇数和偶数是的情况
          //奇数时最中间是一个字符 i
          int len1 = center(s, i, i);
          //偶数时最中间是两个字符 i 和 i-1
          int len2 = center(s, i, i + 1);
          //分别将得到的两个最长回文子串比较取出最大的值
          int len = Math.max(len1, len2);
          if(len > right - left) {
              //然后判断分别得出最长回文子串的最小下标和最大的下标
              //这个公式对于奇数个和偶数个都是用
              left = i - (len - 1) / 2;
              right = i + len / 2;
          }
      }
      return s.substring(left, right + 1);
        }

//创建一个方法用来体现中心扩展算法,判断从i开始的字符串向两边延伸从而得到最长回文字符串
    public int center(String s, int left, int right){
        //当满足left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right条件时 可以判断为是回文子串
        while(left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            --left;
            ++right;
        }
        //返回回文字符串下标之间的距离
        return right -left - 1;
    }

}

(3) Manacher 算法

之后补充 点击爱寂寞的时光博客

(4)动态规划

使用动态规划算法,在暴力破解的基础上降低了时间复杂度

动态规划就是通过牺牲空间的做法来实现时间上的更优

image-20220417172913582

class Solution {
    public String longestPalindrome(String s) {
        //使用动态规划方式进行求解
         int len = s.length();
         if(len < 2){
             return s;
         }

         //定义两个边界值
         int maxLen = 1;
         int begin = 0;

         //开始使用动态规划算法
         //dp[i][j]表示s[i ,j]是否是回文串

         boolean[][] dp = new boolean[len][len];
         char[] Array = s.toCharArray();

         //二维数组中的对角线取不到值, 所以进行初始化
         //二维数组中横坐标表示数组的右边界值,纵坐标是左边界值
         for(int i = 0; i < len; i++) {
             dp[i][i] = true;
         }

         for(int j = 1; j < len; j++) {
             for(int i = 0; i < j; i++) {
                 if(Array[i] != Array[j]) {
                     dp[i][j] = false;
                 }else{
                     if(j - i < 3) {
                         dp[i][j] = true;
                     }else{
                         dp[i][j] = dp[i + 1][j - 1];
                     }
                 }
                 //只要dp[i][j] == true 成立,则表示s[i...j]为回文串
                 if(dp[i][j] && j - i + 1 > maxLen) {
                     maxLen = j -i + 1;
                     begin = i;
                 }
             }
         }
         return s.substring(begin, begin + maxLen);
        }
}

参考LeetCode

posted @ 2022-05-22 23:04  Root-RockMan  阅读(20)  评论(0编辑  收藏  举报