Problem: 5. 最长回文子串
文章目录
- 题目描述
- 思路
- 复杂度
- Code
题目描述
思路
思路1:双指针
1.我们利用双指针从中间向两边扩散来判断是否为回文串,则关键是找到以s[i]为中心的回文串;
2.我们编写一个函数string palindrome(string &s, int left, int right)用于返回以索引为i作为中心向两边的的回文子串
3.由于可能出现奇数或者偶数长度的回文串,所以我们需要在遍历时,求出**palindrome(s, i, i)与palindrome(s, i, i + 1)**的回文串,并取出其中的较大值
思路2:动态规划
1.状态定义:dp[i][j]表示s[i…j]是回文字符串(定义为bool类型若为true则表示是回文串);
2.状态初始化:所有长度为0的均为回文串,即dp[i][i] == true;
3.状态转移:若s[i] != s[j],则dp[i][j] == false,若s[i] = s[j],则dp[i][j] = dp[i + 1][j - 1]
复杂度
思路1:
时间复杂度:
O ( N 2 ) O(N^2) O(N2);其中 N N N为字符串的长度
空间复杂度:
O ( N ) O(N) O(N)
思路2:
时间复杂度:
O ( N 2 ) O(N^2) O(N2);其中 N N N为字符串的长度
空间复杂度:
O ( N 2 ) O(N^2) O(N2)
Code
思路1:
class Solution {
public:
/**
* Two pointer
*
* @param s Given string
* @return string
*/
string longestPalindrome(string s) {
string res;
for (int i = 0; i < s.size(); ++i) {
// Longest callback substring centered on s[i] (odd)
string s1 = palindrome(s, i, i);
// Longest palindromic string centered on s[i] and s[i + 1] (even number)
string s2 = palindrome(s, i, i + 1);
res = res.size() > s1.size() ? res : s1;
res = res.size() > s2.size() ? res : s2;
}
return res;
}
/**
* Gets the longest palindrome string between [left,right]
*
* @param s Given string
* @param left Left pointer
* @param right Right pointer
* @return string
*/
string palindrome(string &s, int left, int right) {
while (left >= 0 && right < s.size() && s.at(left) == s.at(right)) {
left--;
right++;
}
return s.substr(left + 1, right - left - 1);
}
};
思路2:
class Solution {
public:
/**
* Dynamic programming
*
* @param s Given string
* @return string
*/
string longestPalindrome(string s) {
int len = s.length();
if (len < 2) {
return s;
}
int maxLen = 1;
int begin = 0;
// dp[i][j] Indicates whether s[i..j] is a palindrome string
vector<vector<bool>> dp(len, vector<bool>(len));
for (int i = 0; i < len; ++i) {
dp[i][i] = true;
}
for (int L = 2; L <= len; ++L) {
// Initialization: All substrings of length 1 are palindromes
for (int l = 0; l < len; ++l) {
// L and l can determine the right boundary, that is, r - l + 1 = L
int r = L + l - 1;
// If the right boundary is out of bounds, you can exit the current loop
if (r >= len) {
break;
}
if (s.at(l) != s.at(r)) {
dp[l][r] = false;
} else {
if (r - l < 3) {
dp[l][r] = true;
} else {
dp[l][r] = dp[l + 1][r - 1];
}
}
// As long as dp[i][L] == true is true, it means that
// the substring s[i..L] is a palindrome,
// in which case the palindrome length and starting position are recorded
if (dp[l][r] && r - l + 1 >= maxLen) {
maxLen = r - l + 1;
begin = l;
}
}
}
return s.substr(begin, maxLen);
}
};