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.html
For example:算法
Given "aacecaaa"
, return "aaacecaaa"
.this
Given "abcd"
, return "dcbabcd"
.spa
Credits:
Special thanks to @ifanchu for adding this problem and creating all test cases. Thanks to @Freezen for additional test cases.code
https://leetcode.com/problems/shortest-palindrome/orm
其實問題能夠轉化成求從s[0]開始的最長迴文,找到以s[0]開始的最長迴文,將剩下的部分倒序補在字符串前面就是答案。在找以s[0]開始的迴文的時候,能夠從後向前枚舉迴文結束的字符,在第一個找到的地方退出便可。最壞狀況下時間複雜度爲O(n^2),用C語言提交AC,704ms。htm
1 bool isPalindrom(char* s, int start, int end) { 2 while (start < end) { 3 if (s[start] != s[end]) return false; 4 ++start; --end; 5 } 6 return true; 7 } 8 9 char* shortestPalindrome(char* s) { 10 int pos = strlen(s) - 1; 11 for (; pos > 0; --pos) { 12 if (s[pos] == s[0] && isPalindrom(s, 0, pos)) break; 13 } 14 char* res = (char*) malloc(2 * strlen(s) - pos); 15 int idx = 0; 16 for (int i = strlen(s) - 1; i > pos; --i) res[idx++] = s[i]; 17 strcpy(res + idx, s); 18 return res; 19 }
可是用C++提交後超時,可能這並非最佳的答案吧,想到更好的方法後再回來補上代碼(已經想到了,見後文)。blog
1 class Solution { 2 public: 3 bool isPalindrom(string &s, int start, int end) { 4 while (start < end) { 5 if (s[start] != s[end]) return false; 6 ++start; --end; 7 } 8 return true; 9 } 10 string shortestPalindrome(string s) { 11 int pos = s.length() - 1; 12 if (pos == 0) return s; 13 for (; pos > 0; --pos) { 14 if (s[pos] == s[0] && isPalindrom(s, 0, pos)) break; 15 } 16 string res; 17 for (int i = s.length() - 1; i > pos; --i) res.push_back(s[i]); 18 res += s; 19 return res; 20 } 21 };
求最長迴文的Manacher算法時間複雜度爲O(n),能夠用在這裏,可是在判斷最長迴文的時候須要加一個條件,就是隻比較那些以s[0]開始的迴文,而根據Manacher算法的特性,id == p[id]時迴文必定是從s[0]開始的。因此下面也是用C++寫能夠AC的代碼,由於時間複雜度是O(n),因此只用了16ms。關於Manacher算法,能夠看我另外一篇文章:ci
http://www.cnblogs.com/easonliu/p/4454213.htmlleetcode
1 class Solution { 2 public: 3 int longestPalindrom(string s) { 4 string s1; 5 s1.resize(2 * s.length() + 2); 6 int idx = 0; 7 s1[idx++] = '$'; 8 s1[idx++] = '#'; 9 for (char a : s) { 10 s1[idx++] = a; 11 s1[idx++] = '#'; 12 } 13 vector<int> p(s1.length(), 0); 14 int res = 0; 15 for (int id = 0, i = 1; i < s1.length(); ++i) { 16 if (i < id + p[id]) p[i] = min(p[2 * id - i], id + p[id] - i); 17 else p[i] = 1; 18 while (s1[i + p[i]] == s1[i - p[i]]) ++p[i]; 19 if (id + p[id] < i + p[i]) id = i; 20 if (p[i] == i) res = max(res, i); 21 } 22 return res - 1; 23 } 24 25 string shortestPalindrome(string s) { 26 int pos = longestPalindrom(s); 27 string res; 28 for (int i = s.length() - 1; i >= pos; --i) res.push_back(s[i]); 29 return res + s; 30 } 31 };