【问题标题】:Leetcode: Time limit exceeded, Longest palindromic substring [closed]Leetcode:超过时间限制,最长回文子串 [关闭]
【发布时间】:2022-07-16 21:54:44
【问题描述】:

我正在尝试解决 LeetCode 问题5. Longest palindromic substring

给定一个字符串s,返回s中最长的回文子串。

我在非常长的字符串(最多 1000 个字符)上超出了时间限制,但另一方面,在我的终端上使用相同的长字符串可以立即给我正确的答案。这是我得到错误的字符串:

"zudfweormatjycujjirzjpyrmaxurectxrtqedmmgergwdvjmjtstdhcihacqnothgttgqfywcpgnuvwglvfiuxteopoyizgehkwuvvkqxbnufkcbodlhdmbqyghkojrgokpwdhtdrwmvdegwycecrgjvuexlguayzcammupgeskrvpthrmwqaqsdcgycdupykppiyhwzwcplivjnnvwhqkkxildtyjltklcokcrgqnnwzzeuqioyahqpuskkpbxhvzvqyhlegmoviogzwuiqahiouhnecjwysmtarjjdjqdrkljawzasriouuiqkcwwqsxifbndjmyprdozhwaoibpqrthpcjphgsfbeqrqqoqiqqdicvybzxhklehzzapbvcyleljawowluqgxxwlrymzojshlwkmzwpixgfjljkmwdtjeabgyrpbqyyykmoaqdambpkyyvukalbrzoyoufjqeftniddsfqnilxlplselqatdgjziphvrbokofvuerpsvqmzakbyzxtxvyanvjpfyvyiivqusfrsufjanmfibgrkwtiuoykiavpbqeyfsuteuxxjiyxvlvgmehycdvxdorpepmsinvmyzeqeiikajopqedyopirmhymozernxzaueljjrhcsofwyddkpnvcvzixdjknikyhzmstvbducjcoyoeoaqruuewclzqqqxzpgykrkygxnmlsrjudoaejxkipkgmcoqtxhelvsizgdwdyjwuumazxfstoaxeqqxoqezakdqjwpkrbldpcbbxexquqrznavcrprnydufsidakvrpuzgfisdxreldbqfizngtrilnbqboxwmwienlkmmiuifrvytukcqcpeqdwwucymgvyrektsnfijdcdoawbcwkkjkqwzffnuqituihjaklvthulmcjrhqcyzvekzqlxgddjoir"

您可以在下面找到我提交的代码。我想知道如何优化我的代码代码的基本思想是我使用滑动窗口技术在每次迭代时创建一个子字符串,并使用辅助方法检查子字符串是否为回文。

例子:

如果我的字符串是“babad”。第一个子字符串将是整个字符串 (babad)。显然,它不是回文,因此通过减小右侧窗口,我可以重新检查字符串是否是回文。在第二次迭代中,窗口现在是字符串大小 - 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;
  }
};

【问题讨论】:

  • 你复制的字符串太多了。可能不应该复制一次。
  • 你的解法是正确的,但是你需要使用动态规划来避免不必要的重新计算。看看这个:youtube.com/watch?v=PY9sl9QZqSs&t=1673s

标签: c++ string algorithm c++17 sliding-window


【解决方案1】:

该算法从外向内工作会浪费大量时间。意识到回文有一个“中心”(在相邻索引上或相邻索引之间),您的算法通常会使用 same 中心但尺寸减小的回文来查找回文。您可以通过从内到外的工作来减少工作,即选择所有可能的中心,并查看具有该中心的最大回文数。这样,您每个中心只需进行一次扫描。因此,遍历所有可能的中心(on 索引和 两个索引之间),看看哪个是您可以通过这种方式找到的最大回文。

然后您可以从字符串中间的中心开始进一步优化(因为它们可能提供最大的字符串),然后将您的中心“扇形”远离字符串中间,直到 em> 你离字符串的外端太近了,无法改进你已经找到的最长回文。

最后,避免创建新字符串,只使用索引(左、右、...等),只有在您已经确定了开始/结束索引时才真正创建字符串最大的回文。

【讨论】:

    猜你喜欢
    • 2019-03-03
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    • 2023-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多