挺簡單的一道題,一開始以爲會TLE,沒想到居然過了。
轉一個特別的的方法,雖然不一定更快。號稱O(n)實際上肯定不是:
http://www.cnblogs.com/wuyiqi/archive/2012/06/25/2561063.html
void pk()
{
int i;
int mx = 0;
int id;
for(i=1; i<n; i++)
{
if( mx > i )
p[i] = MIN( p[2*id-i], mx-i );
else
p[i] = 1;
for(; str[i+p[i]] == str[i-p[i]]; p[i]++)
;
if( p[i] + i > mx )
{
mx = p[i] + i;
id = i;
}
}
}
leetcode後面大部分是提問的。不過有幾個思想挺有意思的:把字符串反轉,找最長相同子串,一個細節是要找位置跟中軸對稱的子串比較。
還有一個寫錯了的code找的是就算中間被隔斷開也算迴文的最長迴文子串。用的是DP思想。
我的代碼:
class Solution {
public:
string longestPalindrome(string s) {
int i,i2, j, n = s.length();
if (n < 2 || (n == 2 && s[0] == s[1]))
{
return s;
}
int max = 0, start = 0;
for (i = 0; i < n-1; i++)
{
i2 = i;
while (s[i2]==s[i2+1])
{
i2++;
}
for (j = 1; ; j++)
{
if (i < j || i2 + j > n - 1 || s[i-j] != s[i2+j])
{
break;
}
}
if ( 2 * (j - 1) + i2 - i > max)
{
max = 2 * (j - 1) + i2 - i;
start = i - j + 1;
}
i = i2;
}
return s.substr(start, max + 1);
}
};
找可以被隔開的迴文的代碼:
string longestPalindrome(string s) {
int n = s.size();
string dp[1001]; // bottom up
string tmp[1001]; // store a copy of dp
if (n <= 1){
return s;
}
for (int i = 0; i < n; i++){ dp[i] = tmp[i] = ""; }
dp[0] += s[0];
for (int i = 1; i<n; i++){
copy(dp, dp + i + 1, tmp);
dp[i] = string(1, s[i]);
for (int j = i - 1; j >= 0; j--){
if (s[i] == s[j]){
dp[j] = string(1, s[i]) + tmp[j + 1] + string(1, s[i]);
}
else{
if (tmp[j].size() > dp[j + 1].size())
dp[j] = tmp[j];
else
dp[j] = dp[j + 1];
}
}
}
return dp[0];
}