LeetCode T5 Longest Palindromic Substring

题目地址:

中文:https://leetcode-cn.com/problems/longest-palindromic-substring/
英文:https://leetcode.com/problems/longest-palindromic-substring/

题目描述:

Given a string s, return the longest palindromic substring in s.

Example 1:

Input: s = “babad”
Output: “bab”
Note: “aba” is also a valid answer.

Example 2:

Input: s = “cbbd”
Output: “bb”

Example 3:

Input: s = “a”
Output: “a”

Example 4:

Input: s = “ac”
Output: “a”

Constraints:

1 <= s.length <= 1000
s consist of only digits and English letters (lower-case and/or upper-case),

思路:

思路1:暴力,会超时

列举所有子串,挨个判断。
列举所有字串要O(n^2)的复杂度(见题解1,是n(n-1)/2)。
然后对每个字串进行回文判断是个O(n)的。
所以最终是O(n^3)的复杂度。

思路2:优化暴力

上述暴力方法虽然会超时,但是可以进行优化。在暴力过程中,比如“cbabc”,在计算过“bab”是回文串之后,遍历到“cbabc”仍会进行一遍完整的比对,其中包含了很多重复计算。
思路2就是要利用这些重复计算,使用中心扩散的思想,用一个二维数组dp[i][j]来记录i到j的回文串长度,首先初始化所有i=j的长度为1,初始化相邻的相同字母为dp[i][i+1]=2。
然后,对每个dp[i][j]不为0的情况,以其为中心扩散,判断s[i-1]和s[j+1]是否相同,如果相同的话就继续扩散,这样就避免了重复计算。

结果应该还能优化。。因为时间上我只超过了18%的人。

还有个动规的思路。。待做。。。

题解:

题解1:暴力(不通过)
class Solution {
    public static String longestPalindrome(String s) {
        int max_cnt = 0;
        int temp;
        String res = "";
        for(int i=0;i<s.length();i++){
            for(int j=i+1;j<=s.length();j++){
                if(is_back(s.substring(i,j))){
                    temp = j-i;
                    if(temp>max_cnt){
                        res = s.substring(i,j);
                        max_cnt = temp;
                    }
                }

            }
        }
        return res;
    }

    public static boolean is_back(String s){
        int len = s.length();
        for(int i=0;i<len/2;i++)
            if(s.charAt(i)!=s.charAt(len-i-1))
                return false;
        return true;
    }
}
题解2:中心扩散AC
class Solution {
    public static String longestPalindrome(String s) {
        int len = s.length();
        int dp[][] = new int[len][len];
        int back_len_max = 1;
        String back_srt_max = String.valueOf(s.charAt(0));
        //下面定义两个初始状态
        for(int i=0;i<len;i++)
            for(int j=0;j<len;++j)
                if(i==j) dp[i][j] = 1;
                else dp[i][j] = 0;
        for(int i=len-1;i>0;--i) if(s.charAt(i)==s.charAt(i-1)){
            dp[i-1][i] = 2;
            back_len_max = 2;
            back_srt_max = s.substring(i-1,i+1);
        }

        for(int i=0;i<len;++i)
            for(int j=i;j<len;++j)
                if(dp[i][j]!=0){
                    int m = i-1;
                    int n = j+1;
                    while(m>=0 && n<len && s.charAt(m)==s.charAt(n)){
                        if(n-m+1>back_len_max){
                            back_srt_max = s.substring(m,n+1);
                            back_len_max = n-m+1;
                            dp[m][n] = back_len_max;
                        }
                        m -= 1;
                        n += 1;
                    }
                }

        return back_srt_max;

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值