【问题标题】:C++ time limit exceeded when it doesn't even execute the function当它甚至不执行函数时超出了 C++ 时间限制
【发布时间】:2021-07-12 00:30:43
【问题描述】:

当我在 LeetCode 中解决一个问题时,我发现了一些很奇怪的东西。

我有这条线,我认为它给了我一个超出时间限制的错误:

s.erase(i-k, k);

当我评论(//)这一行时,它没有显示时间超过错误,但奇怪的是,即使我没有评论它也从未执行过。

下面是整个代码。 Here 是问题链接。

class Solution {
public:
    string removeDuplicates(string s, int k) {
        char prev = s[0];
        int cnt = 1;
        cnt = 1;

        for(int i = 1; i < s.size() + 1; i++){
            if(s[i] == prev){
                cnt++;
            } else {
                if(cnt == k){
                    // when input is "abcd" it never comes to this scope
                    // which is impossible to run erase function. 
                    s.erase(i-k, k);

                    i = 0;
                }
                
                if(i >= s.size()) break;
                
                cnt = 1;
                prev = s[i];
            }
        }
        
        return s;
    }
};

当 Input 为 "abcd" 时,它甚至不会进入 'erase' 函数所在的 if 范围。 虽然 'erase' 函数从未运行过,但它仍然会影响时间复杂度,我不明白原因。

有人能解释一下吗?还是这只是 LeetCode 的问题?

【问题讨论】:

  • 我不知道原因。 -- 你为什么认为你的程序是正确的,而失败的原因是“LeetCode”或其他什么?这看起来像是一个程序错误,您需要通过 using a debugger 解决,就像所有程序员在程序行为不正确时应该做的一样。

标签: c++ time-complexity std


【解决方案1】:

当程序遇到严重错误(编码错误)和/或崩溃时,许多在线比赛服务器会报告 Time Exceeding。

例如读取超出数组范围的错误。或取消引用坏(垃圾)指针。

为什么超时。因为严重错误程序可能会挂起和/或崩溃。这意味着它也不会及时提供结果。

所以我认为你必须调试你的程序来发现所有的编码错误,而不是花时间优化算法。

关于这一行s.erase(i-k, k); - 它可能会在i &lt; k 时崩溃/挂起,然后你有负值,这是.erase() 方法不允许的。例如,当您获得 i - k 等于 -1 时,size_t 类型(擦除的第一个参数的类型)将溢出(环绕)到值 18446744073709551615,这绝对超出范围,超出内存边界,因此您的程序可能会崩溃和/或挂起。当删除的字符太多时,擦除也会崩溃,即擦除s.erase(a, b)你必须注意a + b &lt;= s.size(),它不受擦除功能的控制。

参见擦除方法的documentation,不要将负值作为该方法的参数。检查你的算法永远不会有负值,即在调用s.erase(i-k, k);时永远不会有i &lt; k,也永远不会有i-k + k &gt; s.size()。为确保没有程序崩溃,您可以执行以下操作:

int start = std::min(std::max(0, i-k), int(s.size()));
int num = std::min(k, std::max(0, int(s.size()) - start));
s.erase(start, num);

【讨论】:

  • 通常当它由于运行时错误而崩溃时,它们会告诉我发生了哪些运行时错误...我检查了 (i-k > 0) 是否为真,但我会尝试使用您的示例!谢谢:)
  • @JongWookKim 通常但并非总是如此,有时由于错误程序只是挂起,没有响应或崩溃。然后他们的服务器无法区分您的程序是由于严重错误还是因为它正在执行长时间计算而挂起,对于服务器而言,这两种情况看起来相同,这就是为什么它只是说 Time Exceeded。关于i-k&gt;0,请注意您必须检查i-k&gt;=0,而不是&gt;0。您还必须检查(i-k) + k &lt;= s.size()。您必须检查范围的两个部分,左侧和右侧。检查这两个条件,看看程序是否仍然因 TIME Exceeding 而崩溃?
猜你喜欢
  • 1970-01-01
  • 2020-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-24
  • 2019-08-28
相关资源
最近更新 更多