Leetcode - Longest Palindrome Substring

<div class="it610-blog-content-contain" style="font-size: 14px"></div>
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.
[balabala] Method1从小到大逐一check不同长度的子串是否为回文,使用DP保存中间计算,但仍然会超时,Method3是非DP版的Method1,1年前的历史记录竟然是Accept的,估计当时leetcode 打瞌睡了。Method2 同样是DP,能够被Accept,分析计算次数和Method1一样,在Eclipse下实际运行超时的case,后者比前者快三、四ms,我认为差异主要是因为Method1 访问数组的模式不如Method2优,将二维数组看成一个矩阵,Method1 不断在各行间跳跃访问,而Method2 在一次外层循环中逐列访问同一行的数组。Method4是从当前1个字符或当前两个字符向两边辐射求得最长回文,该方法比Method2效率更高,因为它避免了一些无意义的计算,比如“abcdefg”, Method1和2均需要计算全部子串,而Method4不会计算诸如abcde这样的子串,在计算bcd时即停止计算其余以c为中心的子串。还有一种 O(n)的实现,还未看懂, http://www.cnblogs.com/tenosdoit/p/3675788.html 先备忘着。

[ref]
http://www.cnblogs.com/tenosdoit/p/3675788.html
http://www.cnblogs.com/jdflyfly/p/3810674.html
http://codeganker.blogspot.com/2014/02/longest-palindromic-substring-leetcode.html

// Method 1: O(n^2), time out
    public String longestPalindrome1(String s) {
        if (s == null || s.equals(""))
            return "";
        int n = s.length();
        boolean[][] dp = new boolean[n][n];
        for (int i = 0; i < n; i++)
            dp[i][i] = true;
        String ans = s.substring(0, 1);
        for (int i = 0; i < n - 1; i++) {
            dp[i][i + 1] = s.charAt(i) == s.charAt(i + 1);
            if (ans.length() == 1 && dp[i][i + 1])
                ans = s.substring(i, i + 2);
        }
        
        for (int l = 3; l <= n; l++) {
            for (int i = 0; i + l <= n; i++) {
                int j = i + l - 1;
                dp[i][j] = s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1];
                if (ans.length() < l && dp[i][j])
                    ans = s.substring(i, i + l);
            }
        }
        return ans;
    }
    
    // Method 2: O(n^2) 另一种DP实现
    // http://codeganker.blogspot.com/2014/02/longest-palindromic-substring-leetcode.html
    public String longestPalindrome(String s) {
        if (s == null || s.equals(""))
            return "";
        int n = s.length();
        String ans = "";
        int maxLen = 0;
        boolean[][] dp = new boolean[n][n];
        for (int i = n - 1; i >= 0; i--) {
            for (int j = i; j < n; j++) {
                if (s.charAt(i) == s.charAt(j) && (j - i < 2 || dp[i + 1][j - 1])) {
                    dp[i][j] = true;
                    if (maxLen < j - i + 1) {
                        maxLen = j - i + 1;
                        ans = s.substring(i, j + 1);
                    }
                }
            }
        }
        return ans;
    }
    
    // Method 3: O(n^2), from up to bottom, once accept, time out now
    public String longestPalindrome3(String s) {
        if (s == null || s.equals(""))
            return "";
        int n = s.length();
        for (int len = n; len >= 1; len--) {
            for (int i = 0; i + len <= n; i++) {
                String sub = s.substring(i, i + len);
                if (isPalin(sub)) {
                    return sub;
                }
            }
        }
        return "";
    }
    private boolean isPalin(String s) {
        int i = 0, j = s.length() - 1;
        while (i < j) {
            if (s.charAt(i) != s.charAt(j))
                return false;
            i++;
            j--;
        }
        return true;
    }
    
    // Method 4: O(n^2) 以当前字符或者当前字符及下一个字符向外辐射找出最长的子串
    // http://www.cnblogs.com/jdflyfly/p/3810674.html
    public String longestPalindrome4(String s) {
        if (s == null || s.equals(""))
            return "";
        int n = s.length();
        int maxLen = 1;
        int tmpLen = 0;
        String ans = s.substring(0, 1);
        for (int i = 0; i < n - 1; i++) {
            tmpLen = getPalin(s, i - 1, i + 1);
            if (tmpLen > maxLen) {
                int start = i - tmpLen / 2;
                ans = s.substring(start, start + tmpLen); 
                maxLen = tmpLen;
            }
            tmpLen = getPalin(s, i, i + 1);
            if (tmpLen > maxLen) {
                int start = i - tmpLen / 2 + 1;
                ans = s.substring(start, start + tmpLen);
                maxLen = tmpLen;
            }
        }
        return ans;
    }
    
    private int getPalin(String s, int left, int right) {
        int n = s.length();
        int len = right - left - 1;
        while (left >= 0 && right < n) {
            if (s.charAt(left--) == s.charAt(right++)) {
                len += 2;
            } else {
                return len;
            }
        }
        return len;
    }

你可能感兴趣的:(substring)