leetcode 5 :Longest Palindromic Substring 找出最长回文子串

题目:

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

翻译:

找出字符串s中最长的回文子串,字符串s的最长是1000,假设存在唯一的最长回文子串

法一:直接暴力破解

O(N3)的时间复杂度,运行超时:

Java程序:

public class Solution {
    public String longestPalindrome(String s) {
        // isPalindrome(s);
        int sLen = s.length();
        int maxLen = 0;
        String maxSubStr="";
        if(sLen==1) return s;
        for(int i=0;i<sLen;i++){
            for(int j=i+1;j<sLen-1;j++){
                String subStr = s.substring(i,j+1);
                if(isPalindrome(subStr)){
                    int tmp = subStr.length();
                    if(tmp >maxLen){
                        maxLen = tmp;
                        maxSubStr = subStr;
                    }
                }
            }
        }
        return maxSubStr;
    }
    boolean isPalindrome(String s){
        int sLen = s.length();
        if(sLen==1) return true;
        for(int i = 0;i<sLen/2;i++){
            char left = s.charAt(i);
            char right = s.charAt(sLen - i -1);
            if(left!=right)
                return false;
        }
        return true;
    }
}

法二:

网上找个O(N2

定义一个dp矩阵 长度是字符串s的长度

初始值问题:

对角线设为1

为了防止回文序列长度是偶数要对s[i] 与s[i+1]相等作判断

若s[i]== s[j],则dp[i][j] = 1

对于s[i] 到s[j] 部分是否是回文字符串,需要考虑的是s[i+1]到s[j-1]部分是不是回文

可以转化为:若s[i] == s[j] ,则考虑s[i+1] 是否等于s[j-1],这里只需判断最近的一个就好了,因为这是从里面向外面循环的

对于dp矩阵的元素就是:若dp[i][j] = 1,则考虑d[i+1][j-1]是否等于 1,若d[i+1][j-1]=0,则 ,令dp[i][j]=0,里面不回文外面一定不回文。

public String longestPalindrome(String s){
        if(s==null) return null;
        if(s.length()<=1) return s;
        int sLen = s.length();
        int maxLen = 1;
        String longest = null;
        int[][] dp = new int[sLen][sLen];
        // 对角线 1
        for(int i=0;i<sLen;++i)
                dp[i][i]=1;
        // 相邻元素是否相等,主要是用来判断回文长度是偶数
        for(int i=0;i<sLen-1;++i){
            if(s.charAt(i)==s.charAt(i+1)){
                dp[i][i+1] = 1;
                longest = s.substring(i,i+2);
                }
        }
        // 依次遍历所有可能长度的回文数
        for(int k=2;k<sLen;++k){
            for(int i=0;i<sLen-k;++i){
                int j = i+k;
                if(s.charAt(i) == s.charAt(j)){
                    dp[i][j] = dp[i+1][j-1];
                    if(dp[i][j]==1 && k>maxLen)
                        longest = s.substring(i,j+1);
                }else
                    dp[i][j]=0;
            }
        }
        return longest;

    }
Time Limit Exceeded
Last executed input:
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"

这里是全部一样的,执行超时。

增加一个集合用于判断字符串中元素全部一样的情况

运行依旧超时

public class Solution {

  String longestPalindrome(String s){
        if(s==null) return null;
        if(s.length()<=1) return s;
        int sLen = s.length();
        int maxLen = 1;
        String longest = null;
        TreeSet ts = new TreeSet();
        for(int i=0;i<sLen;i++)
            ts.add(s.charAt(i));
         if(ts.size()==1) return s;
        int[][] dp = new int[sLen][sLen];
        // 对角线 1
        for(int i=0;i<sLen;++i)
                dp[i][i]=1;
        // 相邻元素是否相等,主要是用来判断回文长度是偶数
        for(int i=0;i<sLen-1;++i){
            if(s.charAt(i)==s.charAt(i+1)){
                dp[i][i+1] = 1;
                longest = s.substring(i,i+2);
                }
        }
        // 依次遍历所有可能长度的回文数
        for(int k=2;k<sLen;++k){
            for(int i=0;i<sLen-k;++i){
                int j = i+k;
                if(s.charAt(i) == s.charAt(j)){
                    dp[i][j] = dp[i+1][j-1];
                    if(dp[i][j]==1 && k>maxLen)
                        longest = s.substring(i,j+1);
                }else
                    dp[i][j]=0;
            }
        }
        return longest;

    }
}

依旧超时:

Last executed input:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

法三:

时间复杂度:O(N2)

空间复制度:O(1)

也是来源于上面链接中的程序

这里的思想是:对应字符串中的i位置,向两侧依次判断是否相等,遇到第一个不相等的时候,结束判断

对应最大回文长度是偶数的,要先判断s[i]与s[i+1]是否相等后,再作上面类似的操作

这个AC了

class Solution{
    String longestPalindrome(String s){
        if(s.isEmpty()) return null;
        if(s.length() == 1) return s;
        String longest = s.substring(0,1);
        for(int i=0;i<s.length();++i){
            // 这里考虑的是回文长度是奇数的情况
            String tmp = longestPalindromeCenter(s,i,i);
            if(tmp.length() > longest.length())
                longest = tmp;
            //偶数时候
            if(i<s.length() -1  &&  s.charAt(i)==s.charAt(i+1) ){
                tmp = longestPalindromeCenter(s,i,i+1);
                if(tmp.length() > longest.length())
                    longest = tmp;
            }
        }
        return longest;
    }
    String longestPalindromeCenter(String s,int left,int right){
        while(left>=0 && right< s.length() && s.charAt(left)== s.charAt(right)){
            left--;
            right++;
        }// 以s[i] 为中心向两侧扩展,直到不满足回文的条件结束
        return s.substring(left+1,right);// 结束的时候已经执行了left--  right++ 要去掉
    }
}

上面的对于是偶数的可以不要判断,因为在下面的while中有先对这个两个起始点的判断了

对应的Python程序:

class Solution(object):
    def longestPalindrome2(self, s):
        longest = ‘‘
        if len(s)<=1 : return s
        sLen = len(s)
        for i in range(sLen):
            tmp = self.longestPalindromeCenter(s,i,i)
            if len(tmp) > len(longest):
                longest = tmp
#             if i<sLen-1 and s[i]==s[i+1]:
#                 tmp = self.longestPalindromeCenter(s, i, i+1)
#                 if len(tmp)>len(longest):
#                     longest = tmp
#             if i<sLen-1 and s[i]==s[i+1]:
            tmp = self.longestPalindromeCenter(s, i, i+1)
            if len(tmp)>len(longest):
                    longest = tmp
        return longest

    def longestPalindromeCenter(self, s,left,right):
        while(left>=0 and right<len(s) and s[left]==s[right]):
            left-=1
            right+=1
        return s[(left+1):right]

    def longestPalindrome(self, s):
        if len(s)<=1: return s
        sLen = len(s)
        dp = [[0 for _ in range(sLen)] for _ in range(sLen)]
        longest=""
        for i in range(sLen):
            dp[i][i] = 1
        for i in range(sLen-1):
            if s[i]==s[i+1]:
                dp[i][i+1] = 1
                longest = s[i:(i+2)]
        for k in range(2,sLen):
            for i in range(0,sLen-k):
                j = i + k
                if s[i]==s[j]:
                    dp[i][j]=dp[i+1][j-1]
                    if dp[i][j]==1 and len(s[i:(j+1)])>len(longest):
                        longest = s[i:(j+1)]
                else:
                    dp[i][j] = 0
        return longest

依旧是根据中心点查找的AC,下面一个时间超时

附几个让你超时的测试字符串:

String s1="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        String s2="cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc";
        String s3 = "vmqjjfnxtyciixhceqyvibhdmivndvxyzzamcrtpywczjmvlodtqbpjayfchpisbiycczpgjdzezzprfyfwiujqbcubohvvyakxfmsyqkysbigwcslofikvurcbjxrccasvyflhwkzlrqowyijfxacvirmyuhtobbpadxvngydlyzudvnyrgnipnpztdyqledweguchivlwfctafeavejkqyxvfqsigjwodxoqeabnhfhuwzgqarehgmhgisqetrhuszoklbywqrtauvsinumhnrmfkbxffkijrbeefjmipocoeddjuemvqqjpzktxecolwzgpdseshzztnvljbntrbkealeemgkapikyleontpwmoltfwfnrtnxcwmvshepsahffekaemmeklzrpmjxjpwqhihkgvnqhysptomfeqsikvnyhnujcgokfddwsqjmqgsqwsggwhxyinfspgukkfowoxaxosmmogxephzhhy";
时间: 2024-10-04 10:56:24

leetcode 5 :Longest Palindromic Substring 找出最长回文子串的相关文章

LeetCode 5 Longest Palindromic Substring manacher算法,最长回文子序列,string.substr(start,len) 难度:2

https://leetcode.com/problems/longest-palindromic-substring/ manacher算法相关:http://blog.csdn.net/ywhorizen/article/details/6629268 class Solution { public: string longestPalindrome(string s) { char ch[2001];int p[2001]; ch[2*s.size()] = 0; for(int i =

找出最长回文子串之Manacher算法

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 1.暴力求解. 计算字符串的最长回文字串最简单的算法就是枚举该字符串的每一个子串,并且判断这个子串是否为回文串,这个算法的时间复杂度为O(n^3)的,

LeetCode: Longest Palindromic Substring(Medium)

原题链接:https://leetcode.com/problems/longest-palindromic-substring/description/ 1. 题目要求:找出字符串中的最大回文子串 2. 注意:要考虑回文子串中的字符个数是奇数还是偶数!!! 例如,"aabaa"是一个奇数个字符的回文字符串,他的中心只有一个字符"b". "aabbaa"是一个偶数个字符的回文字符串,他的中心却有两个相同字符"bb" 3. 思路

[LeetCode]33. Longest Palindromic Substring最长回文子串

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 解法一:考虑回文字符串paliStr的特征,分为字符串长度为奇偶两种情况:(1)paliStr.size()为奇数时,则从最中间的一个字符往两边扩展是

【LeetCode】Longest Palindromic Substring 解题报告

DP.KMP什么的都太高大上了,自己想了个朴素的遍历方法. [题目] Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. [思路](应该算是O(n)吧) 从中间向两端搜索,分别找到以每个字母为中心的最长

LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法

LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法 题记 本文是LeetCode题库的第五题,没想到做这些题的速度会这么慢,工作之余全部耗在这上面了,只怪自己基础差.本文主要介绍使用Manacher线性算法来求解字符串的最长回文子字符串. 题目 Given a string S, find the longest palindromic substring in S. You may assume that the maxim

LeetCode 5. Longest Palindromic Substring(medium难度)

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. Example: Input: "babad" Output: "bab" Note: "aba" is also a valid answer. Example: Input: "cbbd" Ou

LeetCode #5 Longest Palindromic Substring (M)

[Problem] Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. [Analysis] 这题的思路有很多种,网上也有各种讨论.这里我采用的是个人觉得比较好理解的一种利用Dynamic Progra

【Leetcode】Longest Palindromic Substring

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 以每个字符为中心,向两侧拓展,找最长回文子串. 1 class Solution { 2 public: 3 string longestPalind