最长回文子串
【题目描述】
给定一个字符串 s,找到 s 中最长的回文子串,你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案 (官方题解)
【解题思路】
1:中心扩展法: 按照回文串的定义细分为几种情况讨论即可 (奇数回文, 偶数回文, 相同字符回文),
也可见官方题解用动态规划 或 Manacher算法来优化
【字符串操作补充】
要记得哟!!!!!
1. 截取子串
s.substr(pos, n) 截取s中从pos开始(包括0)的n个字符的子串,并返回
s.substr(pos) 截取s中从从pos开始(包括0)到末尾的所有字符的子串,并返回
2. 替换子串
s.replace(pos, n, s1) 用s1替换s中从pos开始(包括0)的n个字符的子串
3. 查找子串
s.find(s1) 查找s中第一次出现s1的位置,并返回(包括0)
s.rfind(s1) 查找s中最后次出现s1的位置,并返回(包括0)
s.find_first_of(s1) 查找在s1中任意一个字符在s中第一次出现的位置,并返回(包括0)
s.find_last_of(s1) 查找在s1中任意一个字符在s中最后一次出现的位置,并返回(包括0)
s.fin_first_not_of(s1) 查找s中第一个不属于s1中的字符的位置,并返回(包括0)
s.fin_last_not_of(s1) 查找s中最后一个不属于s1中的字符的位置,并返回(包括0)
【样例代码】
#include<iostream>
#include<string>
using namespace std;
class Solution {
public:
string longestPalindrome(string s) {
string s1;
int i = 0, max = 0;
int n = s.length();
for (int i = 0; i < n-1; i++)
{ // 判断 bbbbbb, aabbbbbbbcf, 这种回文串为相同字符情况
int k = 0;
for (int j = i + 1; j < n; j++)
{
if (s[i] != s[j]) break; //跳出内层循环, 继续外层循环
else
{
k++;
if (k > max)
{ // 找到更长的回文串, 长度 max和s1 回文串 不断更新改变
max = k;
s1 = s.substr(i, k + 1);
}
}
}
}
for ( i = 1; i < n-1; i++)
{
int k1 = 0, k2 = 0;
for (int j1 = 1, j2 = 1; ; )
{
if ( (j1 <= i && j1 <= n - 1 - i) && s[i - j1] == s[i + j1] )
{//加上j1 <= i, 为判断 abcdcbf 类奇数个对称情况
k1++; j1++; // k1: 记录奇数类时, 关于i位置两边对称相同字符长度
}
else if ( (j2 <= i + 1 && j2 <= n - 1 - i) && s[i + 1 -j2] == s[i + j2] )
{/ 加上 j2 <= i+1 为判断 cabbac 类偶数个对称
k2++; j2++; // k2: 记录偶数类时, 两边对称相同字符长度
}
else break; / 注意j++ 满足的条件, 即一旦不成立跳出!!!
}
if (k1 != 0 && 2 * k1 + 1 > max)
{
max = 2 * k1 + 1; / (奇数类) 最大长度
s1 = s.substr(i - k1, 2 * k1 + 1); //截取最长回文串
}
if (2 * k2 > max)
{
max = 2 * k2; / (偶数类) 最大长度
s1 = s.substr(i + 1 - k2, 2 * k2); //截取最长回文串
}
}
if (max == 0) { s1 = s[0]; } //极端情况
return s1;
}
};
int main()
{
Solution S;
string s;
cin >> s;
cout << S.longestPalindrome(s);
}