Leetcode:【DP】Longest Palindromic Substring 解题报告

Longest Palindromic Substring -- HARD 级别

Question SolutionGiven 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.


经典的DP题目。

主页君给出3种解法:

1. Brute Force

GitHub代码链接

这个非常Straight Forward,就是开始节点i从0-len-1遍历一次,结束结点以i - Len-1遍历一次。每个字符串都
判断它是不是回文,判断是不是回文也可以使用递归来做。总的复杂度是
Time:O(n^3), Space:O(1)

2. DP

DP 因为是二维动态规划 
Time:O(n^2), Space:O(n^2)

 1 public String longestPalindrome(String s) {
 2         if (s == null) {
 3             return null;
 4         }
 5
 6         String ret = null;
 7
 8         int len = s.length();
 9         int max = 0;
10
11         boolean[][] D = new boolean[len][len];
12
13         for (int j = 0; j < len; j++) {
14             for (int i = 0; i <= j; i++) {
15                 D[i][j] = s.charAt(i) == s.charAt(j) && (j - i <= 2 || D[i + 1][j - 1]);
16                 if (D[i][j]) {
17                     if (j - i + 1 > max) {
18                         max = j - i + 1;
19                         ret = s.substring(i, j + 1);
20                     }
21                 }
22             }
23         }
24
25         return ret;
26     }

请戳主页君的代码哦

解说:
状态表达式:D[i][j] 表示i,j这2个索引之间的字符串是不是回文。
递推公式: D[i][j] = if ( char i == char j) && (D[i + 1][j - 1]  ||  j - i <= 2)) 这个很好理解,跟递归是一个意思,只不过 动规的好处就是我们可以重复利用这些结果。

初始化:
D[i][i] = true;实际上也不用特别初始化,都可以套到递推公式里头。 所以主页君的代码会看起来很简单。

注意:用max记录回文长度,回文找到时,更新一下max,及结果的起始地址,结束地址。

现在重点来了,我们怎么设计这个动规才可以重复利用呢?

从这里可以看出D[i + 1][j - 1], 我们推i,j的时候用到了i+1, j-1,其实意思就是在计算i,j时,关于同一个j-1的所有的i必须要计算过。

画图如下:
1. 00
2. 00 01
         11
3. 00 01 02
         11 12
              22
3. 00 01 02 03                       
         11 12 13
              22 23  
                   33

看到上面的递推关系了吗?只要我们一列一列计算,就能够成功地利用这个动规公式。这也是动态规划的关键性设计所在。
如果你不知道如何设计,就和主页群一样,画一个图来看我们计算某值的时候,需要哪些已经有的值。如上图所示,我们需要的是i+1, j - 1,实际上就是左下角的值,这样的话我们只要一列一列计算,就能成功动态规划。
注意:一行一行计算就会失败!

所以我们的循环的设计是这样的:
for (int j = 0; j < len; j++) 
  { for (int i = 0; i <= j; i++) {

具体请参见代码,慢慢感受一下。这个才是动规的精髓咯。

3. 中心展开法。

这个方法其实很直观,就是从头扫描到尾部,每一个字符以它为中心向2边扩展,扩展到不能扩展为止(有不同的字符),返回以每一个字符为中心的回文,然后不断更新最大回文并返回之。

算法简单,而且复杂度为O(n^2),空间复杂度为O(1)
推荐面试使用这一种方法。据说有的公司如EBAY会拒掉动规的解法. ORZ.. 其实主页君比较心水第二种解法啊,多优美,第三种解法虽然消耗更少,但没有什么普适性。

 1 public class Solution {
 2     public String longestPalindrome(String s) {
 3         if (s == null) {
 4             return null;
 5         }
 6
 7         String ret = null;
 8
 9         int len = s.length();
10         int max = 0;
11         for (int i = 0; i < len; i++) {
12             String s1 = getLongest(s, i, i);
13             String s2 = getLongest(s, i, i + 1);
14
15             if (s1.length() > max) {
16                 max = Math.max(max, s1.length());
17                 ret = s1;
18             }
19
20             if (s2.length() > max) {
21                 max = Math.max(max, s2.length());
22                 ret = s2;
23             }
24         }
25
26         return ret;
27     }
28
29     public String getLongest(String s, int left, int right) {
30         int len = s.length();
31         while (left >= 0 && right < len) {
32             // when i is in the center.
33             if (s.charAt(left) != s.charAt(right)) {
34                 break;
35             }
36
37             left--;
38             right++;
39         }
40
41         return s.substring(left + 1, right);
42     }
43 }

中心展开法代码

其它比较牛的解法:http://blog.csdn.net/hopeztm/article/details/7932245

Ref: http://blog.csdn.net/fightforyourdream/article/details/21309759
       http://blog.163.com/zhaohai_1988/blog/static/2095100852012716105847112/
       http://blog.csdn.net/fightforyourdream/article/details/15025663

时间: 2024-11-10 00:52:25

Leetcode:【DP】Longest Palindromic Substring 解题报告的相关文章

【LeetCode】Longest Palindromic Substring 解题报告

DP.KMP什么的都太高大上了,自己想了个朴素的遍历方法. [题目] 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. [思路](应该算是O(n)吧) 从中间向两端搜索,分别找到以每个字母为中心的最长

Longest Palindromic Substring 解题报告

使用马拉车算法,时间复杂度为O(n),算法详细解释在上一篇文章中. // // main.cpp // Longest Substring // // Created by Bowie Hsu on 14/11/21. // Copyright (c) 2014年 Bowie Hsu . All rights reserved. // #include <iostream> #include <string> #include <sstream> #include &l

LeetCode #5 Longest Palindromic Substring (M)

[Problem] 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. [Analysis] 这题的思路有很多种,网上也有各种讨论.这里我采用的是个人觉得比较好理解的一种利用Dynamic Progra

LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法

LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法 题记 本文是LeetCode题库的第五题,没想到做这些题的速度会这么慢,工作之余全部耗在这上面了,只怪自己基础差.本文主要介绍使用Manacher线性算法来求解字符串的最长回文子字符串. 题目 Given a string S, find the longest palindromic substring in S. You may assume that the maxim

Java for LeetCode 005 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. 解题思路一: 暴力枚举 共N^2量级个子串(从下标零开始),每次检查需一个for循环,等于是3重for循环,时间复杂度O(n^3) 解题思路二: 动态

LeetCode:Longest Palindromic Substring

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. 动态规划解法 T(n) = O(n^2)  ,S(n) = O(n^2); Solutio

Java [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. 解题思路: 遍历方法,时间复杂度为O(n).首先从字符串的开头位置一直往后遍历,在每次遍历的过程中由该位置向两边扩散,直到找到最长的子回文

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