leetcode5.最长回文子串——学习笔记

题目:力扣icon-default.png?t=L9C2https://leetcode-cn.com/problems/longest-palindromic-substring/

方法一:暴力解法

class Solution {
    public String longestPalindrome(String s) {
        String f = new String();
        if(s.length()==1){
            f = s;
        }else{
            int count = 0;
            for(int i=0;i<s.length();i++){
                int temp=0;
                for(int j=i-1;j>0;j--){
                    String str = s.substring(j,i);
                    boolean check = checkPalindrome(str);
                    if(check){
                        temp = temp+1;
                        if(temp>count){
                            count = temp;
                            f = str;
                        }
                    }else{
                        break;
                    }
                }
            }
        }
        return f;
    }

    public boolean checkPalindrome(String s){
        char[] temp = s.toCharArray();
        int flag=1;
        int i=0;
        int j = s.length()-1;
        boolean k = true;
        while(flag==1){
            if(i>=j){
                flag = 0;
            }else if(temp[i]!=temp[j]){
                flag = -1;
            }

            i = i++;
            j = j--;
            if(flag==0||flag==-1){
                break;
            } 
        }
        if(flag==0){
            k = true;
        }else if(flag==1){
            k = false;
        }
        return k;
    }
}

 结果是:

        上面是我第一次写的代码,写完之后一执行就被leetcode报“超出时间限制”,至于上面代码的正确性我倒也没有检验,这个方法一不是重点。这个方法思路很无脑,就是先写一个“检测是否为回文”的方法,从头到尾枚举再调用这个方法检验。提醒一下,其实是有暴力解法不超时的,但是我写的不是最简最优的暴力解法。(其实也是我不愿意在暴力解法上做优化了,于是去学习然后重新换了个思路。)

方法二:中心扩散

class Solution {
    public String longestPalindrome(String s) {
        if(s.length()<1){
            return "";
        }
        int len1;
        int len2;
        int len;
        int start=0;
        int end=0;
        for(int i=0;i<s.length();i++){
            len1 = checkPla(s,i,i);
            len2 = checkPla(s,i,i+1);
            len = Math.max(len1,len2); 
            if(len>end-start){
                start = i-(len-1)/2;
                end = i+len/2;
            }
        }
        return s.substring(start,end+1);
    }

    private int checkPla(String s,int left,int right) {
        int L = left, R = right;
        while (L>=0 && R<s.length() && s.charAt(L)==s.charAt(R)) {
            L--;
            R++;
        }
        return R-L-1;
    }
}

 

思路:因为暴力解法的效率低,所以这里采取了中心扩散法。顾名思义,其实就是枚举“中心”可能出现的位置。回文的定义就是,在中心左右的两个字符相等,那么就可以先写一个私有的方法实现这一操作,然后再调用。具体视频如下。

最长回文子串演示

1.检查回文的方法。private表示这个方法是私有的,判断左右是否越绝,字符是否相等,若都符合要求则确定是回文,然后继续向左向右扩散,重复上述判断直至判断不合要求位置,计算其长度最后返回。

private int checkPla(String s,int left,int right) {
    int L = left, R = right;
    while (L>=0 && R<s.length() && s.charAt(L)==s.charAt(R)) {
        L--;
        R++;
    }
    return R-L-1;
}

2.对特殊情况的处理,增强健壮性。

if(s.length()<1){
    return "";
}

3.声明各种变量。len1是“中心”在字符时判断回文的最长长度;len2是“中心”在字符时判断回文的最长长度;len是在i一样时,取上述两种方法所得回文长度较长的一种方法;start是表示当回文长度达到当前最长时的起始位置;end是表示当回文长度达到当前最长时的终止位置。

int len1;
int len2;
int len;
int start=0;
int end=0;

4.i在一个位置时,用len1(“中心”在字符上)与len2(“中心”在字符间)两种方法分别判断最长回文长度,len取上述两者较大者,若len大于先前记录下来的最大长度,则更新start(起始位置)和end(终止)。

for(int i=0;i<s.length();i++){
    len1 = checkPla(s,i,i);
    len2 = checkPla(s,i,i+1);
    len = Math.max(len1,len2); 
    if(len>end-start){
        start = i-(len-1)/2;
        end = i+len/2;
    }
}

5.最后返回从其实位置至终止位置的子串即可。注意下标的处理。

return s.substring(start,end+1);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hokachi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值