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"
Output
: "bb"
hint1
:
How can we reuse a previously computed palindrome to compute a larger palindrome?
hint2
:
If “aba” is a palindrome, is “xabax” and palindrome? Similarly is “xabay” a palindrome?
hint3
:
Complexity based hint:
If we use brute-force and check whether for every start and end position a substring is a palindrome we have O(n^2) start - end pairs and O(n) palindromic checks. Can we reduce the time for palindromic checks to O(1) by reusing some previous computation.
题目大意:
给定一个字符串s,找出它的最长回文子串,字符串s的长度不超过1000。
解题思路:
首先分析题目返回值,和昨天的找出最长子串的长度不一样,这个是要找出长串,也就意味着要么把最长子串的长度和开始下表记录下来,要么得另外找容器记录最长子串。
来看题目要求,找出最长回文子串,两个限定,回文和最长。第一想法简单的就是找出所有回文子串存到某个容器中,再输出长度最长的即可,但这样无疑效率是最低的,而且题目有提示可以尝试O(1)时间复杂度内解决。
O(1)时间复杂度解决,那么很明显字符串只遍历了一次,我开始想的是前后设置一个指针逐步往中间逼近,但是发现这样做的复杂度还是O(n^2),再看看提示2,其实可以从中间散开而不是从两边逐渐逼近。
解题代码:
class Solution {
public:
string longestPalindrome(string s)
{
/*边界情况检查*/
if (s.size() < 2)
return s;
/*
left :左指针
right :右指针
flag :哨兵,用来表示遍历过程中最新位置
max_s :最长回文子串长度
max_l :最长回文子串开始所在的下标
*/
int left, right, size = s.size(), flag = 0, max_s = 0, max_l = 0;
/*哨兵点开始设置在第一位*/
while (flag < size)
{
/*设置左右两个指针,每次flag更新后指针向两边散开*/
left = flag;
right = flag;
/*如果发现同样字符,那么很明显是回文,右指针继续往右走,直到找到不一样的,并更新flag,下次寻找从这里展开*/
while (right + 1 < size && s[right] == s[right + 1]) right++;
flag = right + 1;
/*找到了不一样的,两个指针中间可能有同一个字符的回文,也可能没有,无所谓,接下来是要比较两个指针对应的字符是否相同*/
while (left - 1 >= 0 && right + 1 < size && s[left - 1] == s[right + 1])
{
left--;
right++;
}
/*此时回文长度已更新,与之前所保存的最长回文长度作比较,更新最长回文长度及下标*/
if (right - left + 1 > max_l)
{
max_l = right - left + 1;
max_s = left;
}
}
return s.substr(max_s, max_l);
}
};
网友评论