Leetcode:超出时间限制,最长回文子串
Leetcode: Time limit exceeded, Longest palindromic substring
我正在尝试解决 LeetCode 问题 5. Longest palindromic substring:
Given a string s
, return the longest palindromic substring in s
.
我收到超长字符串(最多 1000 个字符)的时间限制,但另一方面,在我的终端上使用相同的长字符串会立即给出正确答案。这是我收到错误的字符串:
"zudfweormatjycujjirzjpyrmaxurectxrtqedmmgergwdvjmjtstdhcihacqnothgttgqfywcpgnuvwglvfiuxteopoyizgehkwuvvkqxbnufkcbodlhdmbqyghkojrgokpwdhtdrwmvdegwycecrgjvuexlguayzcammupgeskrvpthrmwqaqsdcgycdupykppiyhwzwcplivjnnvwhqkkxildtyjltklcokcrgqnnwzzeuqioyahqpuskkpbxhvzvqyhlegmoviogzwuiqahiouhnecjwysmtarjjdjqdrkljawzasriouuiqkcwwqsxifbndjmyprdozhwaoibpqrthpcjphgsfbeqrqqoqiqqdicvybzxhklehzzapbvcyleljawowluqgxxwlrymzojshlwkmzwpixgfjljkmwdtjeabgyrpbqyyykmoaqdambpkyyvukalbrzoyoufjqeftniddsfqnilxlplselqatdgjziphvrbokofvuerpsvqmzakbyzxtxvyanvjpfyvyiivqusfrsufjanmfibgrkwtiuoykiavpbqeyfsuteuxxjiyxvlvgmehycdvxdorpepmsinvmyzeqeiikajopqedyopirmhymozernxzaueljjrhcsofwyddkpnvcvzixdjknikyhzmstvbducjcoyoeoaqruuewclzqqqxzpgykrkygxnmlsrjudoaejxkipkgmcoqtxhelvsizgdwdyjwuumazxfstoaxeqqxoqezakdqjwpkrbldpcbbxexquqrznavcrprnydufsidakvrpuzgfisdxreldbqfizngtrilnbqboxwmwienlkmmiuifrvytukcqcpeqdwwucymgvyrektsnfijdcdoawbcwkkjkqwzffnuqituihjaklvthulmcjrhqcyzvekzqlxgddjoir"
您可以在下面找到我提交的代码。我想知道如何优化我的代码(或者如果它不好的话可能重新开始)。代码的基本思想是,我使用滑动 window 技术在每次迭代时创建一个子字符串,并使用辅助方法检查该子字符串是否为回文。在运行时开始时,我的 window 等于字符串的大小,并且随着每次迭代逐渐变小。一旦找到回文子串,它就会 return 子串。
示例:
如果我的字符串是“babad”。第一个子字符串将是整个字符串 (babad)。显然,它不是回文,所以通过减少右边的 window 我可以重新检查字符串是否是回文。在第二次迭代中,window 现在是字符串大小 - 1,这给了我们两个子字符串(baba 和 abad),这两个子字符串都不是回文,因此它会继续,直到它偶然发现一个回文子字符串。我的第一个提交是使用双 for 循环的天真的暴力破解,这给了我 O(n^2) 的复杂性,但我真的不明白为什么这个新版本会很慢的问题。
感谢任何帮助。
class Solution {
public:
bool ispalindrome(string s) {
int i = 0, j = s.size() - 1;
while(i <= j){
if(s[i] != s[j]){
return false;
}
i++;
j--;
}
return true;
}
string longestPalindrome(string s) {
int window_size = s.size() - 1;
int left = 0, right = window_size;
string tmp_str = "";
while (right < s.size()) {
tmp_str.append(s.begin() + left, s.begin() + right + 1);
if (ispalindrome(tmp_str)) {
return tmp_str;
}
if((right + 1) < s.size()) {
tmp_str = "";
right++;
left++;
} else {
tmp_str = "";
window_size--;
right = window_size;
left = 0;
}
}
return s;
}
};
该算法从外向内工作会浪费大量时间。意识到回文有一个“中心”(在相邻索引上或之间),并且您的算法通常会使用 相同 中心但尺寸减小来寻找回文。您可以通过从内向外工作来减少工作,即 select 所有可能的中心,并查看具有该中心的最大回文是什么。这样您每个中心只会进行一次扫描。因此,遍历所有可能的中心(on 索引和 between 两个索引),看看哪个是您可以通过这种方式找到的最大回文.
然后您可以进一步优化,方法是从弦中间的中心开始(因为它们可能提供最大的弦),然后将您的中心“散开”远离弦的中间,直到你离字符串的外端太近,使得不可能改进你已经找到的最长回文。
最后,避免创建新的字符串,只使用索引(左、右、...等),只有在你已经确定了字符串时才真正创建一个字符串start/end最大回文的索引。
我正在尝试解决 LeetCode 问题 5. Longest palindromic substring:
Given a string
s
, return the longest palindromic substring ins
.
我收到超长字符串(最多 1000 个字符)的时间限制,但另一方面,在我的终端上使用相同的长字符串会立即给出正确答案。这是我收到错误的字符串:
"zudfweormatjycujjirzjpyrmaxurectxrtqedmmgergwdvjmjtstdhcihacqnothgttgqfywcpgnuvwglvfiuxteopoyizgehkwuvvkqxbnufkcbodlhdmbqyghkojrgokpwdhtdrwmvdegwycecrgjvuexlguayzcammupgeskrvpthrmwqaqsdcgycdupykppiyhwzwcplivjnnvwhqkkxildtyjltklcokcrgqnnwzzeuqioyahqpuskkpbxhvzvqyhlegmoviogzwuiqahiouhnecjwysmtarjjdjqdrkljawzasriouuiqkcwwqsxifbndjmyprdozhwaoibpqrthpcjphgsfbeqrqqoqiqqdicvybzxhklehzzapbvcyleljawowluqgxxwlrymzojshlwkmzwpixgfjljkmwdtjeabgyrpbqyyykmoaqdambpkyyvukalbrzoyoufjqeftniddsfqnilxlplselqatdgjziphvrbokofvuerpsvqmzakbyzxtxvyanvjpfyvyiivqusfrsufjanmfibgrkwtiuoykiavpbqeyfsuteuxxjiyxvlvgmehycdvxdorpepmsinvmyzeqeiikajopqedyopirmhymozernxzaueljjrhcsofwyddkpnvcvzixdjknikyhzmstvbducjcoyoeoaqruuewclzqqqxzpgykrkygxnmlsrjudoaejxkipkgmcoqtxhelvsizgdwdyjwuumazxfstoaxeqqxoqezakdqjwpkrbldpcbbxexquqrznavcrprnydufsidakvrpuzgfisdxreldbqfizngtrilnbqboxwmwienlkmmiuifrvytukcqcpeqdwwucymgvyrektsnfijdcdoawbcwkkjkqwzffnuqituihjaklvthulmcjrhqcyzvekzqlxgddjoir"
您可以在下面找到我提交的代码。我想知道如何优化我的代码(或者如果它不好的话可能重新开始)。代码的基本思想是,我使用滑动 window 技术在每次迭代时创建一个子字符串,并使用辅助方法检查该子字符串是否为回文。在运行时开始时,我的 window 等于字符串的大小,并且随着每次迭代逐渐变小。一旦找到回文子串,它就会 return 子串。
示例:
如果我的字符串是“babad”。第一个子字符串将是整个字符串 (babad)。显然,它不是回文,所以通过减少右边的 window 我可以重新检查字符串是否是回文。在第二次迭代中,window 现在是字符串大小 - 1,这给了我们两个子字符串(baba 和 abad),这两个子字符串都不是回文,因此它会继续,直到它偶然发现一个回文子字符串。我的第一个提交是使用双 for 循环的天真的暴力破解,这给了我 O(n^2) 的复杂性,但我真的不明白为什么这个新版本会很慢的问题。
感谢任何帮助。
class Solution {
public:
bool ispalindrome(string s) {
int i = 0, j = s.size() - 1;
while(i <= j){
if(s[i] != s[j]){
return false;
}
i++;
j--;
}
return true;
}
string longestPalindrome(string s) {
int window_size = s.size() - 1;
int left = 0, right = window_size;
string tmp_str = "";
while (right < s.size()) {
tmp_str.append(s.begin() + left, s.begin() + right + 1);
if (ispalindrome(tmp_str)) {
return tmp_str;
}
if((right + 1) < s.size()) {
tmp_str = "";
right++;
left++;
} else {
tmp_str = "";
window_size--;
right = window_size;
left = 0;
}
}
return s;
}
};
该算法从外向内工作会浪费大量时间。意识到回文有一个“中心”(在相邻索引上或之间),并且您的算法通常会使用 相同 中心但尺寸减小来寻找回文。您可以通过从内向外工作来减少工作,即 select 所有可能的中心,并查看具有该中心的最大回文是什么。这样您每个中心只会进行一次扫描。因此,遍历所有可能的中心(on 索引和 between 两个索引),看看哪个是您可以通过这种方式找到的最大回文.
然后您可以进一步优化,方法是从弦中间的中心开始(因为它们可能提供最大的弦),然后将您的中心“散开”远离弦的中间,直到你离字符串的外端太近,使得不可能改进你已经找到的最长回文。
最后,避免创建新的字符串,只使用索引(左、右、...等),只有在你已经确定了字符串时才真正创建一个字符串start/end最大回文的索引。