[LeetCode] 5. Longest Palindromic Substring 最长回文子串

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.

最长回文子串Longest palindromic substring, 最长回文子串或最长对称因子问题是在一个字符串中查找一个最长连续子串,这个子串必须是回文。例如“banana”最长回文子串是“anana”。最长回文子串算法不应当与最长回文子序列算法混淆。

1. 枚举(enumerate): 基于中心点枚举的算法, 遍历数组,以其中的1个元素或者2个元素作为palindrome的中心,通过辅助函数,寻找能拓展得到的最长子字符串。外层循环 O(n),内层循环O(n),因此时间复杂度 Time O(n^2),因为只需要存最长palindrome子字符串本身,空间更优化:Space O(1)

2. 动态归化(DP):

State: dp[i][j], s[i]到s[j]是否构成一个回文

Function: dp[i][j] = s[i] == s[j] &&(j - i <= 2 || dp[i + 1][j - 1])

Initialize: dp[i][j] = true when j - i <= 2

Return: longest substring: longest = s[i, j + 1]

3. Manacher‘s Algorithm,可以达到 O(n) 的线性时间复杂度。

Manacher算法可参考:

Manacher‘s ALGORITHM: O(n)时间求字符串的最长回文子串

Longest Palindromic Substring Part II

Java: 枚举(enumerate), Time: O(n^2), Space: O(1)

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

        int start = 0, len = 0, longest = 0;
        for (int i = 0; i < s.length(); i++) {
            len = findLongestPalindromeFrom(s, i, i);
            if (len > longest) {
                longest = len;
                start = i - len / 2;
            }

            len = findLongestPalindromeFrom(s, i, i + 1);
            if (len > longest) {
                longest = len;
                start = i - len / 2 + 1;
            }
        }

        return s.substring(start, start + longest);
    }

    private int findLongestPalindromeFrom(String s, int left, int right) {
        int len = 0;
        while (left >= 0 && right < s.length()) {
            if (s.charAt(left) != s.charAt(right)) {
                break;
            }
            len += left == right ? 1 : 2;
            left--;
            right++;
        }

        return len;
    }
}

Java: DP, Time: O(n^2), Space: O(n^2)

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

        int n = s.length();
        boolean[][] isPalindrome = new boolean[n][n];

        int longest = 1, start = 0;
        for (int i = 0; i < n; i++) {
            isPalindrome[i][i] = true;
        }
        for (int i = 0; i < n - 1; i++) {
            isPalindrome[i][i + 1] = s.charAt(i) == s.charAt(i + 1);
            if (isPalindrome[i][i + 1]) {
                start = i;
                longest = 2;
            }
        }

        for (int i = n - 1; i >= 0; i--) {
            for (int j = i + 2; j < n; j++) {
                isPalindrome[i][j] = isPalindrome[i + 1][j - 1] &&
                    s.charAt(i) == s.charAt(j);

                if (isPalindrome[i][j] && j - i + 1 > longest) {
                    start = i;
                    longest = j - i + 1;
                }
            }
        }

        return s.substring(start, start + longest);
    }
}

Java: Manacher‘s Algorithm

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

        // abc => #a#b#c#
        String str = generateString(s);

        int[] palindrome = new int[str.length()];
        int mid = 0, longest = 1;
        palindrome[0] = 1;
        for (int i = 1; i < str.length(); i++) {
            int len = 1;
            if (mid + longest > i) {
                int mirrorOfI = mid - (i - mid);
                len = Math.min(palindrome[mirrorOfI], mid + longest - i);
            }

            while (i + len < str.length() && i - len >= 0) {
                if (str.charAt(i - len) != str.charAt(i + len)) {
                    break;
                }
                len++;
            }

            if (len > longest) {
                longest = len;
                mid = i;
            }

            palindrome[i] = len;
        }

        longest = longest - 1; // remove the extra #
        int start = (mid - 1) / 2 - (longest - 1) / 2;
        return s.substring(start, start + longest);
    }

    private String generateString(String s) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            sb.append(‘#‘);
            sb.append(s.charAt(i));
        }
        sb.append(‘#‘);

        return sb.toString();
    }
}

  

  

原文地址:https://www.cnblogs.com/lightwindy/p/8488346.html

时间: 2024-10-11 06:03:40

[LeetCode] 5. Longest Palindromic Substring 最长回文子串的相关文章

[C++]LeetCode: 99 Longest Palindromic Substring (最长回文子串)

题目: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. 思路:题目要求的s的一个最长回文子串.暴力解决办法就是枚举所有的子串,再对每个子串进行回文判断.进行剪枝,我们考虑可以使用动态规划来避免重复的判

[LeetCode]33. Longest Palindromic Substring最长回文子串

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. 解法一:考虑回文字符串paliStr的特征,分为字符串长度为奇偶两种情况:(1)paliStr.size()为奇数时,则从最中间的一个字符往两边扩展是

Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法)

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"

LeetCode 5:Longest Palindromic Substring(最长回文串)

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. 思路一:(超时)简单的截取长度为length(length递减)的字串,判断其是否为回文串.第一个满足要求的回文串最长. public class S

Leetcode 5 Longest Palindromic Substring (最长回文子字符串)(动态规划)

Leetcode 5 题目描述 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: Inp

[Leetcode] Longest palindromic substring 最长回文子串

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. 做这道题之前要先了解什么是回文子串.回文串通俗的解释是,分别从字符串两端开始遍历,得到的结果相同,如"abba",从两端的遍历结果都是:&q

【翻译】Longest Palindromic Substring 最长回文子串

原文地址: http://www.cnblogs.com/zhxshseu/p/4947609.html%20 转载请注明出处:http://www.cnblogs.com/zhxshseu/p/4947609.html 问题描述:Given a string S, find the longest palindromic substring in S. 这道题目是一个经典的动态规划DP http://challenge.greplin.com/问题,在面试中经常会被问到.为什么?因为这个问题可

Longest Palindromic Substring(最长回文子串)

Description: 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: &q

5. Longest Palindromic Substring(最长回文子串 manacher 算法)

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. Example: Input: "babad" Output: "bab" Note: "aba" is also a valid answer. Example: Input: "cbbd" Ou