6.最长回文子串

本文探讨了在给定字符串中查找最长回文子串的两种算法:暴力破解和中心扩展法。暴力破解通过遍历所有子串并检查其是否为回文来确定最长回文子串,而中心扩展法则通过从每个字符向外扩展来查找回文子串,效率更高。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目要求:给定一个字符串 s,找到 s 中最长的回文子串。

示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。

示例 2:
输入: “cbbd”
输出: “bb”

解析:
1.暴力破解,时间复杂度O(n^3)
①首先判断输入的合法性,不合法输出空字符串,即输入字符串为null或为空;
②输入字符串至少有一个字符,则初始最长回文子串为1;
③从字符串开头进行遍历每一个子串,两个for循环;
④判断每个子串是否为回文子串:
两个指针指向子串的首尾,同步逼近,如果出现两个指针指向的字符不是同一个字符,则该子串不为回文子串;如果为回文子串,且长度大于max,更新max值为当前回文子串的长度,同时记录回文子串的首尾索引。
⑤以记录的首尾索引截取最长回文子串,注意包头不包尾规则,尾索引需要+1。

 public String longestPalindrome1(String str){
      if (str == null || str.length() == 0)
       return "";
      int max = 1;//初始最长回文子串的长度
      int start = 0, end = 0;//记录最长回文子串的开始下标结束下标
      for (int  i = 0 ; i < str.length(); i++){//字符串开始
       for (int j = i+1; j < str.length(); j++){//字符串结束
        int tmp1 = i, tmp2 =j;
        //从字符串的首尾开始逼近,判断首尾字符是否相等(包括奇数回文和偶数回文),判断是否为回文子串
        while(tmp2>tmp1 && str.charAt(tmp1)==str.charAt(tmp2)){
         ++tmp1;
         --tmp2;
        }
        //如果str[i,j]为回文子串,则tmp1>=tmp2,比较记录回文子串的长度
        if (tmp1>=tmp2 && (j-i+1)> max){
         max = j-i+1;//更新最长回文子串的长度
         start = i;//最长回文子串的开始索引
         end = j;//最长回文子串的结束索引
        }
       }
      }
      return str.substring(start, end+1);
     }

2.中心扩展(时间复杂度O(n^2)
①首先判断输入的合法性,不合法输出空字符串,即输入字符串为null或为空;
②输入字符串至少有一个字符,则初始最长回文子串为1;
③求奇数位的回文子串的最大长度:
当前字符不动,分别从左右两边同步往外扩展,且两边扩展的字符一致,则为回文子串,记录最大长度;

④求偶数位的回文子串的最大长度:
a.分别从左边和当前字符同步往外扩展,且两边扩展的字符一致,则为回文子串,记录最大长度;
b…分别从当前字符和右边同步往外扩展,且两边扩展的字符一致,则为回文子串,记录最大长度;

if (str == null || str.length() == 0)
       return "";
      int max = 1;//初始最大回文子串
      int start = 0, end = 0;//最大回文子串的开始和结束索引
      //求长度为奇数的回文子串
      for (int i = 0; i < str.length(); i++){
       int left = i-1, right = i+1;
       while (left>=0&&right<str.length()&&str.charAt(left)==str.charAt(right)){
        if (right - left + 1 > max){
         max = right - left + 1;//更新最长回文子串的长度
            start = left;//更新开始索引
            end = right;//更新结束索引
        }
        --left;
        ++right;
       }
      }
      
      //求长度为偶数的回文子串
      for (int i = 0; i < str.length(); i++){
       int left = i-1, right = i;
       while (left>=0 &&right<str.length()&&str.charAt(left)==str.charAt(right)){
        if (right-left+1 > max){
         max = right-left+1;
         start = left;
         end = right;
        }
        --left;
        ++right;
       }
       left = i; right = i+1;
       while (right<str.length()&&left>=0&&str.charAt(left)==str.charAt(right)){
        if (right-left+1 >max){
         max = right -left +1;
         start = left;
         end = right;
        }
        --left;
        ++right;
       }
      }
      return str.substring(start, end+1);//包头不包尾原则
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值