LeetCode 5. Longest Palindromic Substring

文章目录

  • LeetCode 5. Longest Palindromic Substring
    • O(N^2)解法
    • O(N)解法

LeetCode 5. Longest Palindromic Substring


LeetCode题解专栏:LeetCode题解
LeetCode 所有题目总结:LeetCode 所有题目总结
大部分题目C++,Python,Java的解法都有。


题目地址:


Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example 1:

Input: "babad"
Output: "bab"

Note: “aba” is also a valid answer.
Example 2:

Input: "cbbd"
Output: "bb"

这道题目是经典的回文子串,有2种传统解法,一种是O(N^2),一种是O(N)的。

O(N^2)解法

Java代码如下:

class Solution {
 public String longestPalindrome(String s) {
    if (s == null || s.length() < 1) return "";
    int start = 0, end = 0;
    for (int i = 0; i < s.length(); i++) {
        int len1 = expandAroundCenter(s, i, i);
        int len2 = expandAroundCenter(s, i, i + 1);
        int len = Math.max(len1, len2);
        if (len > end - start) {
            start = i - (len - 1) / 2;
            end = i + len / 2;
        }
    }
    return s.substring(start, end + 1);
}

private int expandAroundCenter(String s, int left, int right) {
    int L = left, R = right;
    while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) {
        L--;
        R++;
    }
    return R - L - 1;
}
}

O(N)解法

Java的O(N)解法 如下:

class Solution {
        static public String longestPalindrome(String s) {
        if (s.length() == 0) {
            return "";
        }
        if (s.length() == 1) {
            return s;
        }

        if (s==null || s.length()==0)
            return "";

        char[] s2 = addBoundaries(s.toCharArray());
        int[] p = new int[s2.length];
        int c = 0, r = 0; // Here the first element in s2 has been processed.
        int m = 0, n = 0; // The walking indices to compare if two elements are the same.
        for (int i = 1; i<s2.length; i++) {
            if (i>r) {
                p[i] = 0; m = i-1; n = i+1;
            } else {
                int i2 = c*2-i;
                if (p[i2]<(r-i-1)) {
                    p[i] = p[i2];
                    m = -1; // This signals bypassing the while loop below.
                } else {
                    p[i] = r-i;
                    n = r+1; m = i*2-n;
                }
            }
            while (m>=0 && n<s2.length && s2[m]==s2[n]) {
                p[i]++; m--; n++;
            }
            if ((i+p[i])>r) {
                c = i; r = i+p[i];
            }
        }
        int len = 0; c = 0;
        for (int i = 1; i<s2.length; i++) {
            if (len<p[i]) {
                len = p[i]; c = i;
            }
        }
        char[] ss = Arrays.copyOfRange(s2, c-len, c+len+1);
        return String.valueOf(removeBoundaries(ss));
    }

    private static char[] addBoundaries(char[] cs) {
        if (cs==null || cs.length==0)
            return "||".toCharArray();

        char[] cs2 = new char[cs.length*2+1];
        for (int i = 0; i<(cs2.length-1); i = i+2) {
            cs2[i] = '|';
            cs2[i+1] = cs[i/2];
        }
        cs2[cs2.length-1] = '|';
        return cs2;
    }

    private static char[] removeBoundaries(char[] cs) {
        if (cs==null || cs.length<3)
            return "".toCharArray();

        char[] cs2 = new char[(cs.length-1)/2];
        for (int i = 0; i<cs2.length; i++) {
            cs2[i] = cs[i*2+1];
        }
        return cs2;
    }
}

Python的O(N)解法如下:

class Solution:
    def longestPalindrome(self, s: str) -> str:
        N = len(s) 
        if N < 2: 
            return s
        N = 2*N+1    # Position count 
        L = [0] * N 
        L[0] = 0
        L[1] = 1
        C = 1     # centerPosition 
        R = 2     # centerRightPosition 
        i = 0    # currentRightPosition 
        iMirror = 0     # currentLeftPosition 
        maxLPSLength = 0
        maxLPSCenterPosition = 0
        start = -1
        end = -1
        diff = -1
   
        for i in range(2, N): 
            # get currentLeftPosition iMirror for currentRightPosition i 
            iMirror = 2*C-i 
            L[i] = 0
            diff = R - i 
            # If currentRightPosition i is within centerRightPosition R 
            if diff > 0: 
                L[i] = min(L[iMirror], diff) 
   
            # Attempt to expand palindrome centered at currentRightPosition i 
            # Here for odd positions, we compare characters and 
            # if match then increment LPS Length by ONE 
            # If even position, we just increment LPS by ONE without 
            # any character comparison 
            try:
                while ((i + L[i]) < N and (i - L[i]) > 0) and (((i + L[i] + 1) % 2 == 0) or (s[(i + L[i] + 1) // 2] == s[(i - L[i] - 1) // 2])): 
                    L[i]+=1
            except Exception as e:
                pass
                
            if L[i] > maxLPSLength:        # Track maxLPSLength 
                maxLPSLength = L[i] 
                maxLPSCenterPosition = i 
   
            # If palindrome centered at currentRightPosition i 
            # expand beyond centerRightPosition R, 
            # adjust centerPosition C based on expanded palindrome. 
            if i + L[i] > R: 
                C = i 
                R = i + L[i] 
   
        start = (maxLPSCenterPosition - maxLPSLength) // 2
        end = start + maxLPSLength - 1
        return s[start:end+1]

你可能感兴趣的:(LeetCode,python-做题,java-做题)