Longest Palindromic Substring

Dynamic Programming, String

Medium

Question

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.

Example

Given the string = "abcdzdcab", return "cdzdc".

Challenge

O(n^2) time is acceptable. Can you do it in O(n) time.

Tags

String

Related Problems

Easy Valid Palindrome 22 % Medium Longest Palindromic Substring 26 % Medium Palindrome Partitioning II 22 %

Analysis

区间类动态规划

Time O(n^2), Space O(n^2)

dp[i][j]来存DP的状态,需要较多的额外空间: Space O(n^2)

DP的4个要素

  • 状态:

    • dp[i][j]: s.charAt(i)s.charAt(j)是否构成一个Palindrome

  • 转移方程

    • dp[i][j] = s.charAt(i) == s.charAt(j) && (j - i <= 2 || dp[i + 1][j - 1])

  • 初始化:

    • dp[i][j] = true when j - i <= 2

  • 结果:

    • maxLen = j - i + 1;,并得到相应longest substring: longest = s.substring(i, j + 1);

中心扩展

这种方法基本思想是遍历数组,以其中的1个元素或者2个元素作为palindrome的中心,通过辅助函数,寻找能拓展得到的最长子字符串。外层循环 O(n),内层循环O(n),因此时间复杂度 Time O(n^2),相比动态规划二维数组存状态的方法,因为只需要存最长palindrome子字符串本身,这里空间更优化:Space O(1)

Manacher's Algorithm

这种算法可以达到O(n)时间,但是并不很通用,因此这里略过讨论。具体参考:

Solution

区间DP,Time O(n^2) Space O(n^2)

DP - Time O(n^2), Space O(n^2)

外层循环区间长度,内层循环区间起点

*Another implementation DP - Time O(n^2), space O(n^2)

外层循环区间起点,内层循环区间终点

递推公式中可以看到,首先知道了 i + 1 才会知道 i ,所以只需要倒着遍历i就行了。

类似的,先知道j - 1才知道j,因此顺着遍历j

Space Optimized DP - Time O(n^2), space O(n)

Expand Around Center - Time O(n^2) Space O(1)

Another expand-center implementation

Expand Center - O(n^2) time, O(1) space

@jinwu

7 ms, faster than 99.69%

Reference

Last updated

Was this helpful?