博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Leetcode】Longest Palindromic Substring
阅读量:4876 次
发布时间:2019-06-11

本文共 2527 字,大约阅读时间需要 8 分钟。

问题:

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

 

转载于:https://www.cnblogs.com/coolqiyu/p/5597744.html

你可能感兴趣的文章
三(1)、队列(链队列)
查看>>
DDL(数据定义语言)
查看>>
MySQL存储过程和函数
查看>>
Java 中几种常用设计模式
查看>>
硬盘相关知识
查看>>
[LeetCode] Largest Rectangle in Histogram
查看>>
2345网址导航源码 v3.3
查看>>
字典Dictionary
查看>>
JS重要知识点
查看>>
java解析数据
查看>>
Linux下安装多个tomcat
查看>>
UIPickView之自定义生日键盘和城市键盘
查看>>
改变 C/C++ 控制台程序的输出颜色和样式
查看>>
第1章 游戏之乐——让CPU占用率曲线听你指挥
查看>>
laravel入门教程
查看>>
整理大数据期末考试复习提纲--概念整理
查看>>
线程--promise furture 同步
查看>>
Mybatis3.2.3+mysql第一个例子(入门)
查看>>
Nginx 代理配置
查看>>
跟锦数学171217-180630
查看>>