问题:
难度:medium
说明:
给出一个字符串,找出最长回文子串,子串是字符串集合连续的子集。
题目连接:https://leetcode.com/problems/longest-palindromic-substring/
输入范围:
1 <= s.length <= 1000
s
consist of only digits and English letters (lower-case and/or upper-case),
输入案例:
Example 1:
Input: s = "babad"
Output: "bab"
Note: "aba" is also a valid answer.
Example 2:
Input: s = "cbbd"
Output: "bb"
Example 3:
Input: s = "a"
Output: "a"
Example 4:
Input: s = "ac"
Output: "a"
我的代码:
幸好 1000 以内的长度输入,所以不用怕暴力暴死。
一般就两种情况:
1、奇数 bab 夹在中间的回文字符串是一个字母 a
2、偶数 baab 夹在中间的是 两个 a
然后就是遍历数组,每走一步都判断奇数偶数回文,不过有个方法更好就是直接每走一步,排除掉后续重复的字符。
str = "baab" 假设我走到 str[1] 这个地方,我进行排除重复,如果是 baab 我排除掉 str[2] 再进行回文判断,这样子就少了一次比较,如果是奇数 bab,也不会受影响,因此重复字符越多,效率越高。
Java:
class Solution {
public String longestPalindrome(String s) {
char[] chs = s.toCharArray();
int len = chs.length, cur = 0, max = 0, left = 0;
while(cur < len) {
int tcur = cur, tpre = cur;
while(tcur + 1 < len && chs[tcur] == chs[tcur + 1]) tcur ++; // 排除掉重复
cur = tcur == cur ? cur + 1 : tcur + 1;
while(tpre >= 0 && tcur < len && chs[tcur] == chs[tpre]) {// 再进行回文比较
tcur ++; tpre --;
}
int temp = tcur - tpre - 1;
if(temp > max) { // 获取最长
max = temp; left = tpre + 1;
}
}
return s.substring(left, left + max); // 省了个 right
}
}
C++:
class Solution {
public:
string longestPalindrome(string s) {
int len = s.length(), max = 0, cur = 0, left = 0;
while(cur < len) {
int tcur = cur, tpre = cur;
while(tcur + 1 < len && s[tcur] == s[tcur + 1]) tcur ++;
cur = tcur == cur ? cur + 1 : tcur + 1;
while(tpre >= 0 && tcur < len && s[tpre] == s[tcur]) {
tpre --; tcur ++;
}
int temp = tcur - tpre - 1;
if(temp > max) {
max = temp; left = tpre + 1;
}
}
return s.substr(left, max); // c++是从 i 开始,剪多少个字符
}
};
如果不排除重复,用奇数偶数做法的话,是这样
Java:
public String longestPalindrome(String s) {
char[] chs = s.toCharArray();
int len = chs.length, cur = 1, max = 0, maxLeft = 0, maxRight = 0;
for(;cur < len;cur ++) {
if(chs[cur - 1] == chs[cur]) { // 偶数
int tpre = cur - 1, tcur = cur;
while(tpre >= 0 && tcur < len && chs[tpre] == chs[tcur]) {
tpre --; tcur ++;
}
int temp = tcur - tpre - 1;
if(temp > max) {
maxLeft = tpre + 1; maxRight = tcur - 1; max = temp;
}
}
if(cur + 1 < len && chs[cur + 1] == chs[cur - 1]) { // 奇数
int tpre = cur - 1, tcur = cur + 1;
while(tpre >= 0 && tcur < len && chs[tpre] == chs[tcur]) {
tpre --; tcur ++;
}
int temp = tcur - tpre - 1;
if(temp > max) {
maxLeft = tpre + 1; maxRight = tcur - 1; max = temp;
}
}
}
return s.substring(maxLeft, maxRight + 1);
}