LeetCode 5. Longest Palindromic Substring 最长回文子串(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”

解答:

解法一:O(N^2)

  1. 通过 isPalindromic() 方法判断一个字符串是否为回文字符串
  2. 遍历字符串 s,定义两个指针 i,j,初始状态指向字符串的头部,
    移动指针进行遍历。
  3. 其中,当获得一个回文字符串时,用 location 表示回文字符串的起点标志位,用 length 记录当前长度,在之后的遍历时以 length 值为最小长度值,若之后的子串长度 <= length,即使也是回文字符串也是没有意义的,一定程度上可以减少计算量。
  4. 确定了回文字符串的起始位和长度,就可以利用substring方法,取出该回文子串了。
class Solution {
    public String longestPalindrome(String s) {
        if(s.length() == 0)   return s;
        int length = 1;
        int i = 0;
        int j = 1;
        int location = 0;
        while(i<s.length()-1 && j<s.length()) {
            String substring = s.substring(i,j+1); 
            if(isPalindromic(substring)) {
                if(length < j-i+1) {
                    length = j-i+1;
                    location = i;
                }
            }
            j++;
            if(j == s.length()) {
                i++;
                j = i + length;
            }
        }
        String result = s.substring(location, location+length);
        return result;
    }
    //判断字符串是否为回文字符串
    private boolean isPalindromic(String s) {
        int i = 0;
        int j = s.length()-1;
        while(i<=j) {
            if(s.charAt(i) == s.charAt(j)) {
                i++;
                j--;
            }else{
                return false;
            }
        }
        return true;
    }
}

该算法的时间复杂度为O(n^2) ,空间复杂度为O(n)

String类的substring()方法:用于截取字符串

  1. public String substring(int beginIndex)
    返回一个新字符串,它是此字符串的一个子字符串。该子字符串始于指定索引处的字符,一直到此字符串末尾。
    参数:beginIndex - 开始处的索引(包括)
    异常:如果 beginIndex 为负或大于此 String 对象的长度,则抛出IndexOutOfBoundsException

    "hello".substring(2)   //returns"llo"
    "helloworld".substring(4)    //returns"oworld"
    
  2. public String substring(int beginIndex, int endIndex)
    返回一个新字符串,它是此字符串的一个子字符串。该子字符串从指定的 beginIndex 处开始, 到指定的 endIndex-1处结束。

    参数:beginIndex - 开始处的索引(包括) endindex 结尾处索引(不包括)
    异常:如果 beginIndex 为负,或length大于字符串长度,则抛出IndexOutOfBoundsException

    "helloworld".substring(3,8)  returns "lowor"
    "helloworld".substring(0,5) returns "hello"
    

还有“中心扩展算法",即以当前字符为中心,向其左右两边扩展寻找回文,这种算法需要将字符串分为奇回文(其长度为奇数)、偶回文(其长度为偶数),需要分两种情况来寻找回文。这种解法的时间复杂度仍是O(N^2)

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))

马拉车算法(Manacher’s Algorithm)

你可能感兴趣的:(LeetCode)