LeetcodeLongest Palindromic Substring

Posted 记性不好,多记记吧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetcodeLongest Palindromic Substring相关的知识,希望对你有一定的参考价值。

问题:https://leetcode.com/problems/longest-palindromic-substring/

给定一个字符串 S,求出 S 的最长回文子串

思路:

1. 回文:一个字符串从前和从后读一致。S = "ABBA"  从前读:ABBA,从后读:ABBA

2. 最简单的做法:列出所有的子串,并判断是否是回文,从中找出最长的。

  表格列出了所有的子串,第 i 行是以 S 的第 i 个字符开始的子串。S = "ABBA"

 1  A  AB  ABB  ABBA
 2      B    BB    BBA
 3          B      BA
 4              A

 从最后一行往上,可以看到他们的共同部分,用红色标出。共同的子问题~动态规划。

3. 动态规划,自底向上求解问题 

  1) 对子问题的结果进行存储和表示

  len[i]:包含S[i] 的最长回文子串的长度

  all[i]:S 的后半部分S[i, ..., n - 1] 中的最长回文子串长度 

  2) 把子问题的结果合并成它的上一层

   子问题比它的上一层增加了一个字符。已经求得 S[i+1, ...] 子问题的解:从S[i+1]开始有len[i+1]长的回文子串 S[i+1]~S[n], all[i+1]

   

  ** 如果S[i]和这个子串的后一个字符一样,则从S[i]开始的回文子串可以包含它

  比如:S="ABBA",已知 len[1] = 2,S[0]=S[3]="A",所以len[0] = len[1]+2

  ** 反之,从S[i]开始的回文子串不可以包含它,则需要对该子串从两头开始遍历

      用两个变量分别从头 S[i] 和从尾S[n+1]开始比较,当发生不等的时候,就重新从头开始。

源码 

 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         int ssize = s.length();
 5         int i, j, k, start;
 6         int* len = new int[ssize];
 7         int* all = new int[ssize];
 8         //初始化,最长为1
 9         len[ssize - 1] = all[ssize - 1] = 1;
10         start = ssize - 1;
11         
12         for(i = ssize - 2; i >= 0; --i)
13         {
14             //计算len[i]
15             if(i + len[i + 1] + 1 < ssize && s[i] == s[i + len[i + 1] + 1])//从S[i] 开始的回文子串包含S[i+1]开始的子串
16                 len[i] = len[i + 1] + 2;
17             else//反之需要遍历
18             {
19                 //j, k 表示从S[i] 开始可能的最长回文子串的区间
20                 j = i;
21                 k = i + len[i + 1];
22                 while(j < k)
23                 {
24                     if(s[j] == s[k])
25                     {
26                         ++j;
27                         --k;
28                     }
29                     else//两个字符不同时,j 需从头重新开始
30                     {
31                         j = i;
32                         --k;
33                     }
34                 }
35                 if(i == k && k == j)//
36                     len[i] = 1;
37                 else
38                 {
39                     len[i] = (k - i + 1) * 2;//子串长度为偶数
40                     if(j == k)//子串长度为奇数
41                       len[i]--;
42                 }
43             }
44             //计算all[i]
45             if(len[i] > all[i + 1])
46             {
47                 all[i] = len[i];
48                 start = i;
49             }
50             else
51             {
52                 if(len[i] == all[i + 1])
53                     start = i;
54                 all[i] = all[i + 1];
55             }
56         }
57         delete[] len;
58         delete[] all;
59         return s.substr(start, all[0]);
60     }
61 };
View Code

 

以上是关于LeetcodeLongest Palindromic Substring的主要内容,如果未能解决你的问题,请参考以下文章

LeetcodeLongest Palindromic Substring

ZOJ 1078 Palindrom Numbers

LeetCodeLongest Substring Without Repeating Characters

LeetCodeLongest Common Prefix

LeetcodeLongest Substring Without Repeating Characters

LeetCodeLongest Substring Without Repeating Characters 解题报告