【问题标题】:I have a question I have been trying on LeetCode and needed help in the error which is Time Limit exceeded我有一个问题,我一直在尝试 LeetCode,需要帮助解决超出时间限制的错误
【发布时间】:2020-08-07 19:55:40
【问题描述】:

具体问题的链接如下:https://leetcode.com/problems/nth-magical-number/。我的代码显示“超出时间限制”,我无法弄清楚我的代码中的错误到底在哪里。我的代码如下:

class Solution {
public:
    typedef unsigned int ull;
    int gcd(int A,int B)
    {
        if(B==0)
            return A;
        else
            return gcd(B,A%B);
    }
    int nthMagicalNumber(int N, int A, int B) {
        ull m;
        if(A<B)
        {
           int t;
            t=A;
            A=B;
            B=t;
        }
        ull lcm=(A*B)/gcd(A,B);
        ull l=2;
        ull h=1e9;
        ull n;
        while(l<=h)
        {
            m=l+(h-1)/2;
           n=(m/A)+(m/B)-(m/lcm);
            if(n==N)
                break;
            else if(n<N)
                l=m+1;
            else if(n>N)
                h=m-1;
        }
        ull x=(1e9)+7;
        return (int)(m%x);       
    }
};

谁能让我知道我错在哪里以及如何纠正错误?

【问题讨论】:

  • 超过时间限制并不一定意味着你的代码有错误。这通常意味着您选择的算法效率不足以在所需的时间内解决问题。
  • 超过时间限制几乎总是意味着您的解决方案使用的算法效率不够高,您必须找到更好的算法。你的代码可能有一个可行的算法,但它访问内存的效率很低。
  • 关于 typedef unsigned int ull; 来自名称 ull 我本来期望 typedef unsigned long long ull;。这是因为像这样令人讨厌的惊喜,您应该更喜欢使用像&lt;cstdint&gt; (these for example) 中的标准类型。它们需要更多的输入,但任何熟悉 C 或 C++ 的人都可以立即理解。
  • 你创建这个类有什么原因吗?这些功能可以是独立的。
  • typedef unsigned int ull; - 请不要这样混淆你的代码。

标签: c++ binary-search


【解决方案1】:

您可能希望为此使用调试器。这个解决方案非常相似(使用带有 gcd 的二进制搜索)并且会通过:

// This block might trivially optimize the exec time;
// Can be removed;

const static auto __optimize__ = []() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(NULL);
    return 0;
}();


#include <cstdint>
#include <vector>


const static struct Solution {
    using SizeType = std::uint_fast64_t;
    static constexpr SizeType kMod = 1e9 + 7;
    const SizeType nthMagicalNumber(
        const SizeType N,
        const SizeType A,
        const SizeType B
    ) {
        const SizeType lowest_common_multiple = A * B / getGreatestCommonDivisor(A, B);
        SizeType lo = 2;
        SizeType hi = 1e14;


        while (lo < hi) {
            SizeType mid = lo + (hi - lo) / 2;

            if (mid / A + mid / B - mid / lowest_common_multiple < N) {
                lo = mid + 1;

            } else {
                hi = mid;
            }
        }

        return lo % kMod;
    }

    // __gcd(a, b)
    static const SizeType getGreatestCommonDivisor(
        const SizeType a,
        const SizeType b
    ) {
        if (not b) {
            return a;
        }

        return getGreatestCommonDivisor(b, a % b);

    }
};

这里我们使用的是 std::uint_fast64_t,而不是ull


参考

  • 更多详细信息,请参阅Discussion Board,您可以在其中找到大量解释清楚且公认的解决方案,其中包含多种languages,包括高效算法和渐近time/space 复杂性分析1,2.

【讨论】:

    【解决方案2】:

    对于我的解决方案被接受的问题,您可以在 C++ 中尝试这种方法:

    class Solution {
    public:
        long long gcd(long long a, long long b) {
            if(b == 0)
                return a;
            return gcd(b, a % b);
        }
    
        int nthMagicalNumber(long long n, long long a, long long b) {
            
            long long end = max(a, b) * (n + 1);
            long long min = 1;
            long long lcm = (a / gcd(a, b)) * b;
            long long curr, mid;
            while(min <= end) {
                mid = (end - min)/2 + min;
                
                curr = (mid / a) + (mid / b) - (mid / lcm);
                if(curr > n) {
                    end = mid - 1;
                } else if(curr < n) {
                    min = mid + 1;
                } else {
                    break;
                }
            }
           
            while((mid % a != 0) && (mid % b != 0)) {
                mid--;
            }
            return mid % (1000000007);
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-06
      • 2020-11-09
      • 1970-01-01
      • 2020-08-06
      • 2021-12-11
      • 2023-03-25
      • 2020-08-06
      相关资源
      最近更新 更多