【问题标题】:Faster algorithm than nested loops?比嵌套循环更快的算法?
【发布时间】:2012-04-15 03:38:42
【问题描述】:

对于 google codeJam 资格赛,问题之一是找出两个给定整数之间有多少“回收对”。

这是我的解决方案,但对于大型数据输入集来说速度不够快。给定 @a = 10, @b = 200000 之类的东西,它开始变慢。

我认为我的解决方案是 O(2^n)(我还没有对大 O 分析有扎实的了解),这太可怕了。我想知道是否有一种标准方法可以使用更快的算法迭代这样的两个循环?

def getPairs
    (@a..@b).each do |n|
      (n..@b).each do |m|
        if (containsSame(n,m)) && (isMatch(@a, n, m, @b))
          @recycledPairs += 1
        end
      end
    end
  end

编辑: 来自Google CodeJam site

假设一对不同的正整数 (n, m) 被回收,如果您可以通过将一些数字从 n 的后面移动到前面而不改变它们的顺序来获得 m。例如,(12345, 34512) 是一个循环对,因为您可以通过将 345 从 12345 的末端移到前面来获得 34512。请注意,n 和 m 必须具有相同的位数才能成为循环对。 n 和 m 都不能有前导零。

【问题讨论】:

  • 循环和嵌套循环是实现工件,而不是算法。
  • 来自 google codeJam 网站:假设一对不同的正整数 (n, m) 被回收,如果您可以通过将一些数字从 n 的后面移动到前面而不改变它们的顺序来获得 m。例如,(12345, 34512) 是一个循环对,因为您可以通过将 345 从 12345 的末端移到前面来获得 34512。请注意,n 和 m 必须具有相同的位数才能成为循环对。 n 和 m 都不能有前导零。
  • @JRL:有一种算法叫Nested loop,用在RDBMS中。
  • @AFrase:也许这个MSDN article,关于 SQL-Server 中使用的 3 种不同算法(嵌套循环、哈希连接、合并连接)是有帮助的。它们的表现完全不同,具体取决于数据的大小。还有这篇文章:Nested loops, Hash join and Sort Merge joins – difference?

标签: algorithm loops big-o


【解决方案1】:

您可以阅读the official analysis of this problem 以获得正确的解决方案。

基本上,解决方案是为每个n 计算大于n 但不大于B 的所有不同旋转。

【讨论】:

  • 404,这就是为什么链接需要尽可能将随附的数据复制并粘贴到帖子中
【解决方案2】:

描述说“请注意,n 和 m 必须具有相同的位数才能成为循环对。”

您的内部循环没有考虑到这一点。如果@a = 2 和@b = 20,000,那么你可以切掉整个内循环块。如果n是两位数,那么你只需要测试m的两位数。仔细查看内循环的上限。

【讨论】:

  • 实际的问题陈述还说 A 和 B 的位数也必须相同,所以这无济于事。
【解决方案3】:

从语句中:max b 最多为 2*10^6。与所有 codejam 问题一样,您需要进行多重测试。

第 1 步:预计算。对于每个数字 n = [1..maxb],保存所有从它循环的数字,严格小于它(每个不超过 7)例如

10 - 1
321 - 132, 213

第 2 步:针对每个测试。从 A 到 B 遍历每个数字,并计算 A 和 B 之间“循环”的数量。

时间复杂度:第 1 步适用于每个数字的(位数),即 O(ln n)。你必须做 b 次。总而言之O(b * ln b)。第 2 步也是如此。这在大型测试用例中的工作时间不到一秒。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-06
    • 2019-04-15
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    相关资源
    最近更新 更多