leetcode 5最长回文子串 两种解法

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

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

输入: "cbbd"
输出: "bb"
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


法一:中心扩展法

中心扩展法需要根据对称的是奇数个还是偶数个来进行两次不同的判断。

主要思想就是从任意一个字符串开始,往两边扩散,扩散到不想等,记录下最大的长度。

//中心扩展
    public static String zhongxin(String s){
        if(s.length() ==1 || s.length() == 0){
            return s;
        }
        char[] ch = s.toCharArray();
        int len = s.length();
        int max = 1;
        int start = 0;
        for (int i = 0; i < len; i++) {
            int t1 = i - 1,t2 = i + 1;
            while(t1 >= 0 && t2 < len && ch[t1] == ch[t2]){
                if( t2-t1+1 > max){
                    max = t2 - t1 + 1;
                    start = t1;
                }
                t1--;
                t2++;
            }
        }
        for (int i = 0; i < len; i++) {
            int t1 = i ,t2 = i + 1;
            while(t1 >= 0 && t2 < len && ch[t1] == ch[t2]){
                if( t2-t1+1 > max){
                    max = t2 - t1 + 1;
                    start = t1;
                }
                t1--;
                t2++;
            }
        }
        return s.substring(start,start+max);
    }

法二:动态规划

用一个二维数组来表示是否n(i,j)是否是对称,str(i,j)对称的话,n(i,j)为true;

另外n(i,j)true => n(i+1,j-1) true && str[i] == str[j];

另外用两个标志位记录开始的位置和最长的对称长度。

    public static String longestPalindrome(String s) {
        if(s.equals("")){
            return "";
        }
        int n = s.length();
        int start = 0;
        int len = 1;
        boolean dp[][] = new boolean[n][n];
        for(int i = 0;i < n;i++){
            dp[i][i] = true;
            if(i< n-1 && s.charAt(i) == s.charAt(i+1)){
                dp[i][i+1] = true;
                len = 2;
                start = i;
            }
        }
        for(int l = 3; l <= n;l++){
            for(int i = 0;  i< n-l+1;i++){//i小j大
                int j = l+i-1;
                if(s.charAt(j) == s.charAt(i) && dp[i+1][j-1]){
                    dp[i][j] = true;
                    if(j-i+1>len){
                        len = l;
                        start = i;
                    }
                }
            }
        }
        return s.substring(start,start+len);
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值