LeetCode 5. 最长回文子串

5. 最长回文子串

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

示例 1:

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

示例 2:

输入:s = "cbbd"
输出:"bb"

示例 3:

输入:s = "a"
输出:"a"

示例 4:

输入:s = "ac"
输出:"a"

提示:

  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母(大写和/或小写)组成
/**
    是否是回文?正读反读一样
    boolean dp[i][j]={
        dp[i][j]=dp[i+1][j-1]且dp[i]==dp[j]
    }
**/
class Solution {
    public String longestPalindrome(String s) {
        int len=s.length();
        if(len<2)return s;//空字符串和单字符字符串的回文为本身
        char[] str=s.toCharArray();
        int max=1,index=0;
        boolean[][] dp=new boolean[len][len];
        for(int i=0;i<len;i++) {
        	dp[i][i]=true;
        }
        /**
            自己做了两个从0开始的遍历,出现短字符串还没经历判断的情况
            需要先进行短字符串的回文判断遍历,才能根据已有结果判断长字符串是否回文
            我是伞兵我是伞兵,重复一遍,我是伞兵
        **/
        for(int L=2;L<=len;L++){//需要判断的字符串长度遍历
            for(int i=0;i<len;i++){//遍历字符串左边界
                int j=L+i-1;//获取右边界
                if(j>=len)break;//越界
                if(str[i]==str[j]){
                    if(j-i<=2){
                        dp[i][j]=true;
                    }else{
                        dp[i][j]=dp[i+1][j-1];//i+1不会越界,因为i=len的时候,j越界处理了
                    }
                }else{
                    dp[i][j]=false;
                }
                if(dp[i][j]&&(j-i+1)>max){
                    max=j-i+1;
                    index=i;
                }
            }
        }
        return s.substring(index,index+max);
    }
}

 

/**
    中心扩展,很符合正常人的思考思路
**/
class Solution {
    public String longestPalindrome(String s) {
    	int max=1,start=0,end=0;
    	for(int i=0;i<s.length();i++) {
    		int singleCenter=centerExtend(s,i,i);
    		int doubleCenter=centerExtend(s,i,i+1);
    		max=Math.max(singleCenter, doubleCenter);
    		if(max>end-start) {
    			start=i-(max-1)/2;//这个前索引的计算要注意
    			end=i+(max/2)+1;
    		}
    	}
    	return s.substring(start,end);
    }
    public int centerExtend(String s,int start,int end){
    	while(start>=0&&end<s.length()&&s.charAt(start)==s.charAt(end)) {
    		start--;
    		end++;
    	}
        return end-start-1;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值