您的位置:首页 > 其它

LeetCode之“字符串”:最短回文子串

2015-06-03 13:43 423 查看
  题目链接

  题目要求: 

  Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation.

  For example:

  Given
"aacecaaa"
, return
"aaacecaaa"
.

  Given
"abcd"
, return
"dcbabcd"
.

  这道题用暴力破解是无法通过LeetCode上的测试的。

  1. 法一(暴力破解)

  超过时间!!!!

bool isPalindrome(string  s)
{
int szS = s.size();
for (int i = 0; i < szS / 2; i++)
{
if (s[i] != s[szS - i - 1])
return false;
}
return true;
}

string shortestPalindrome(string s)
{
// clear spaces
if (s.front() == ' ')
s.erase(0, 1);
if (s.back() == ' ')
s.pop_back();
//
string ret;
int szS = s.size();
if (szS == 0)
{
ret = "";
}
else if (szS == 1)
{
s += s;
ret = s;
}
else if (isPalindrome(s))
{
ret = s;
}
else
{
for (int i = 0; i < szS; i++)
{
string tmpStr = s;
for (int j = szS - i - 1; j < szS; j++)
tmpStr.insert(tmpStr.begin(), s[j]);

if (isPalindrome(tmpStr))
{
ret = tmpStr;
break;
}
}
}
return ret;
}


View Code
  看来只能另寻他法了。。。。

  3. 法三

  法三参考自C++ 8 ms KMP-based O(n) time & O(n) memory solution,利用了KMP的思想。具体程序如下:

class Solution {
public:
string shortestPalindrome(string s)
{
string rev_s(s);
reverse(rev_s.begin(), rev_s.end());
string combine = s + "#" + rev_s;   // 防止在匹配的时候,不从‘#’后开始

int sz = combine.size();
vector<int> match(sz, 0);
int k = 0;
for (int i = 1; i < sz; i++) {
while (k > 0 && combine[i] != combine[k])
k = match[k - 1];

if (combine[i] == combine[k])
k = k + 1;

match[i] = k;
}

return rev_s.substr(0, s.size() - match[sz - 1]) + s;
}
};


  上边程序可以解释如下:

  对构造的字符串combine进行匹配操作后,得到如下结果:

  


  匹配部分也就是s和rev_s重复的部分,而不匹配的部分就是它们不一样的部分。接下来的字符串拼接操作就是:

  


  拼接完成后即是最终的结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: