leetcode--day-2

题目

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

解题思路

1.暴力法

#python
def get_longest_Palindromic(s):
    window = 0
    max_len = ""
    while(window <= len(s)):
        for i in range(int(len(s))):
            if i+window >int(len(s)):
                window +=1
                break
            if ispalindromic(s[i:i+window]):
                max_len = s[i:i+window]
                window +=1
                break
    return max_len              
def ispalindromic(s):
    if len(s)%2 == 0:
        mid_index = int(len(s)/2)
    else:
        mid_index = int(len(s)/2+1)
    for i in range(mid_index):
        if s[i] != s[-(i+1)]:
            return False
    return True

由于要判断是否为回文,所以时间复杂度为,空间复杂度为,并不能AC.

2.动态规划法

动态规划相关知识可以点击链接。

#python
class Solution(object):
    def longestPalindrome(self, s):
        dp = [[0]*len(s) for i in range(len(s))]
        max_len = 0
        max_str = ""
        for l in range(len(s)):
            l = l+1
            for start in range(len(s)):
                end = start+l-1
                if end >= len(s):
                    break
                dp[start][end] = (l==1) or (l==2 and (s[start]==s[end])) or (dp[start+1][end-1] and (s[start]==s[end]))
                if dp[start][end] and max_len

动态规划也可以看作是一种更聪明的暴力法,因为可以减少重复计算。时间复杂度和空间复杂度都是

3.中心扩展

我们观察到回文中心的两侧互为镜像。因此,回文可以从它的中心展开,并且只有 2n−1 个这样的中心。你可能会问,为什么会是 2n−1 个,而不是 n 个中心?原因在于所含字母数为偶数的回文的中心可以处于两字母之间(例如 “abba” 的中心在两个 ‘b’ 之间)。

#python
def get_longest_Palindromic_1(s):
    max_len = 0
    s_t = ""
    for i in range(len(s)):
        len1 = expandAroundCenter(s,i,i)#奇数回文串
        len2 = expandAroundCenter(s,i,i+1)#偶数回文串
        len_3 = max(len1,len2)
        if max_len< len_3:
            max_len = len_3
            s_t = s[i-int((max_len-1)/2):i+int(max_len/2)+1]
    return s_t
def expandAroundCenter(s,left,right):
    while(left>=0 and right < len(s) and s[left] == s[right]):
        left = left-1
        right = right +1
    return right-left-1

中心扩展时间复杂度,空间复杂度

Mnacher(马拉车)

算法详情点击链接.

#java
public String preProcess(String s) {
    int n = s.length();
    if (n == 0) {
        return "^$";
    }
    String ret = "^";
    for (int i = 0; i < n; i++)
        ret += "#" + s.charAt(i);
    ret += "#$";
    return ret;
}

// 马拉车算法
public String longestPalindrome2(String s) {
    String T = preProcess(s);
    int n = T.length();
    int[] P = new int[n];
    int C = 0, R = 0;
    for (int i = 1; i < n - 1; i++) {
        int i_mirror = 2 * C - i;
        if (R > i) {
            P[i] = Math.min(R - i, P[i_mirror]);// 防止超出 R
        } else {
            P[i] = 0;// 等于 R 的情况
        }

        // 碰到之前讲的三种情况时候,需要利用中心扩展法
        while (T.charAt(i + 1 + P[i]) == T.charAt(i - 1 - P[i])) {
            P[i]++;
        }

        // 判断是否需要更新 R
        if (i + P[i] > R) {
            C = i;
            R = i + P[i];
        }

    }

    // 找出 P 的最大值
    int maxLen = 0;
    int centerIndex = 0;
    for (int i = 1; i < n - 1; i++) {
        if (P[i] > maxLen) {
            maxLen = P[i];
            centerIndex = i;
        }
    }
    int start = (centerIndex - maxLen) / 2; //最开始讲的求原字符串下标
    return s.substring(start, start + maxLen);
}

你可能感兴趣的:(leetcode--day-2)