LintCode:M-Longest Palindromic Substring

来源:互联网 发布:公安部第三研究所 知乎 编辑:程序博客网 时间:2024/06/07 14:17

LintCode: 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.

Example

Given the string = "abcdzdcab", return "cdzdc".

Challenge 

O(n2) time is acceptable. Can you do it in O(n) time.


(1)O(n)方法:字符串特性,多case分析

(2)动态规划方法,TC = O(n^2)


public class Solution {    /*     * @param s: input string     * @return: the longest palindromic substring     */    //TC = O(n)    //SC = O(n)    public String longestPalindrome_1(String s) {        int n = s.length();                int[] palinStartIndexs = new int[n];//i位置的字符结尾的回文,指向其回文开始位置                //初始各个字符的回文开始为自己的位置        for(int i=0; i<n; i++){            palinStartIndexs[i] = i;        }                int maxLen=1;        int maxStart=0;        for(int i=1; i<n; i++){            int startIndex = palinStartIndexs[i-1];                        //最长的情况:s[i]和前一个回文的前一个相等            if(startIndex-1>=0 && s.charAt(i)==s.charAt(startIndex-1)){                palinStartIndexs[i] = startIndex-1;            }else if(i-1>=0 && s.charAt(i)==s.charAt(i-1)){//次长情况:和前一个字符相等                int sTmp = i-1;                //这一步可以优化,再开辟一个数组,当前i结尾的回文是不是全部字符相等,这样就避免每次都要把回文遍历一遍                //由于s的尺寸不会操过1000,可以给回文的startIndex加上1000,表示是同字符的回文                while(sTmp-1>=0 && s.charAt(i)==s.charAt(sTmp-1)){                    sTmp--;                }                palinStartIndexs[i] = sTmp;            }else if(i-2>=0 && s.charAt(i)==s.charAt(i-2) && s.charAt(i)!=s.charAt(i-1)){//次次长的情况:和前一个字符的再前一个字符相等,相当于把前一个当回文的中间字符,组成奇数回文                palinStartIndexs[i] = i-2;                            }            int parlinLen = i-palinStartIndexs[i]+1;            if(maxLen<parlinLen){                maxLen = parlinLen;                maxStart = palinStartIndexs[i];            }        }                return s.substring(maxStart, maxStart+maxLen);    }        //动态规划    //TC = O(n^2)    //SC = O(n^2)    public String longestPalindrome(String s) {        int n = s.length();        //dp[i][j]表示i~j字符串是否为回文        //当s[i]==s[j],dp[i][j] = dp[i+1][j-1];        //当s[i]!=s[j], dp[i][j] = 0;        boolean[][] dp = new boolean[n][n];                for(int i=0; i<n; i++){            for(int j=0; j<n; j++){                if(i>=j){                    dp[i][j]=true;                }else{                    dp[i][j]=false;                }            }        }                int maxLen=0;        int maxStart=0;        for(int len=2; len<=n; len++){            int j=0;            for(int i=0; i+len-1<n; i++){                j = i+len-1;                if(s.charAt(i)==s.charAt(j)){                    dp[i][j]=dp[i+1][j-1];                    if(dp[i][j]){                        maxLen = len;                        maxStart = i;                    }                }else{                    dp[i][j]=false;                }            }        }                  if(n<2){            return s;        }                return s.substring(maxStart, maxStart+maxLen);    }};


原创粉丝点击