题:力扣
给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母组成
通过次数1,342,682提交次数3,587,244
我的原始思路:
暴力搜索,找出所有字符串,然后判断是否是回文,判断方法为前后比对相等个数。
两层for循环,遍历区间起始位置和终止位置,然后判断这个区间是不是回文。
时间复杂度:O(n^3)
class Solution:
def longestPalindrome(self, s1: str) -> str:
left = 0
right = len(s1) - 1 # 0,30 31
huiwen = " "
maxhuiwen = " "
maxlong = 0
for left in range(0,len(s1)) : #(0,31) [)
for right in range(left+1,len(s1)+1): # 1,0,1,2
s = s1[left:right] # 起点:个数
sleft = 0
sright = len(s) - 1
size = len(s)
if (size % 2 == 0):
numTrue = 0
numloop = size // 2
for sleft in range(0,numloop):
if(s[sleft] == s[sright]):
numTrue = numTrue + 1
sright = sright - 1
if (numTrue == numloop):
huiwen = s
if(size >= maxlong):
maxlong = size
maxhuiwen = huiwen
else:
numTrue = 0
numloop = size // 2 + 1
for sleft in range(0,numloop):
if(s[sleft] == s[sright]):
numTrue = numTrue + 1
sright = sright - 1
if (numTrue == numloop):
huiwen = s
if(size >= maxlong):
maxlong = size
maxhuiwen = huiwen
return maxhuiwen
class Solution {
public:
string longestPalindrome(string s) {
int left = 0;
int right = s.size() - 1;
string huiwen = " ";
string maxhuiwen = " ";
int maxlong = 0;
for (left; left < s.size(); left++) {
for (int k = 1; k < s.size() + 1; k++) {
string str = s.substr(left, k); //string s = "abcdbbfcba"; k是个数,不是位置
int sright = str.size() - 1;
int size = str.size();
if (size % 2 == 0) {
int numTrue = 0;
for (int sleft = 0; sleft < size / 2; sleft++) {
char ssleft = str[sleft];
char ssright = str[sright];
if (ssleft == ssright) {
numTrue = numTrue + 1;
sright = sright - 1;
}
else {
sright = sright - 1;
}
}
if (numTrue == size / 2) {
huiwen = str;
if (size >= maxlong) {
maxlong = size;
maxhuiwen = huiwen;
}
}
}
else {
int numTrue = 0;
for (int sleft = 0; sleft < (size / 2 + 1); sleft++) {
char ssleft = str[sleft];
char ssright = str[sright];
if (ssleft == ssright) {
numTrue = numTrue + 1;
sright = sright - 1;
}
else {
sright = sright - 1;
}
}
if (numTrue == (size / 2 + 1)) {
huiwen = str;
if (size >= maxlong) {
maxlong = size;
maxhuiwen = huiwen;
}
}
}
}
}
return maxhuiwen;
}
};
然而虽然能够求解出来,但是非常耗时,导致超出时间限制。
巧妙思路1:中心扩散法
- 时间复杂度:O(n^2)
一排字符串按照位置循环
每个位置进行奇数偶数两种查找,即向外扩散。
class Solution {
public:
string longestPalindrome(string s) { //string s = "aacabdkacaa";
int len = 0;
int maxlen = 0;
string maxhuiwen = "";
for (int i = 0; i < s.size(); i++) {
int time = 0;
int ttime = 0;
int k = 0;
int j = 0;
int kk = 0;
int jj = 0;
//奇数
for (j = i, k = i; j >=0 && k < s.size(); j--, k++) { //奇数
char left = s[j];
char right = s[k];
if (left == right) {
time = time + 1;
}
else {
break;
}
}
len = time * 2 - 1 ;
if (len >= maxlen) {
maxlen = len;
maxhuiwen = s.substr(i- time+1, len);
}
//偶数
for (jj = i, kk = i+1; jj >= 0 && kk < s.size(); jj--, kk++) { //偶数,bug:检查到不相等还继续找
char ouleft = s[jj];
char ouright = s[kk];
if (ouleft == ouright) {
ttime = ttime + 1;
}
else {
break;
}
}
len = ttime * 2 ;
if (len >= maxlen) {
maxlen = len;
maxhuiwen = s.substr(i - ttime + 1, len);
}
}
return maxhuiwen;
}
};
整理得:
class Solution {
public:
string longestPalindrome(string s) {
for (int i = 0; i < s.size(); i++) {
func(s, i, i); // 奇数长度的子串
func(s, i, i + 1); // 偶数长度的子串
}
return s.substr(start, len);
}
private:
// 用于构造最长子串
int start;
int len = 0;
void func(string& s, int i, int j) {
while (i >= 0 && j < s.size() && s[i] == s[j]) {
if (j - i + 1 > len) {
// 定位暂时最长的子串位置
start = i;
len = j - i + 1;
}
i--;
j++;
}
}
};
——————
浅谈则止,细致入微AI大道理
扫描下方“AI大道理”,选择“关注”公众号
—————————————————————
—————————————————————