美文网首页
leetcode--day-2

leetcode--day-2

作者: zyyupup | 来源:发表于2019-12-26 20:06 被阅读0次

    题目

    给定一个字符串 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
    

    由于要判断是否为回文,所以时间复杂度为O(n^3),空间复杂度为O(1),并不能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<l:
                        max_str = s[start:end+1]
            return max_str
    

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

    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
    

    中心扩展时间复杂度O(n^2),空间复杂度O(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

          本文链接:https://www.haomeiwen.com/subject/njjhoctx.html