【问题标题】:Find the number of pairs whose sum is divisible by k?求总和能被 k 整除的对数?
【发布时间】:2013-09-12 16:19:05
【问题描述】:

给定一个 k 值。这样 k9。

【问题讨论】:

  • 到目前为止,你为这项任务做了什么?
  • 你使用什么语言?
  • 我使用了蛮力技术但失败了
  • 您能否发布您尝试过的代码,以便我们帮助您找出问题所在?
  • 看看this的答案。

标签: numbers combinations combinatorics


【解决方案1】:

我找到了一个解决方案,让ab 数字使得(a+b)%k=0 然后我们必须找到这对(a,b),其中a<b,所以让我们计算有多少对(a,b) 满足a+b=k 的条件,例如如果 k=3 0+3=3, 1+2=3, 2+1=3, 3+0=3 有 4 对,但只有 2 对 (K+1)/2 (integer division) 如此相似,以找到总和为 2k, 3k,.. nk 的对 (a,b),解决方案将是(k+1)/2 + (2k+1)/2 + (3k+1)/2 + ... + (nk+1)/2,这等于 (k*n*(n+1)/2 + n)/2,时间复杂度为 O(1),注意 n*k=2*10^9 的情况,因为对于给定的约束,a 不能超过 10^9

【讨论】:

  • 没有得到这句话“只有2对即(k+1)/2”是什么意思
  • @user765443 因为 (0,3) 与 (3,0) 相同且 (1,2) 与 (2,1) 相同
【解决方案2】:

使用哈希映射解决 O(N) 时间和 O(N) 空间。

概念如下:

If (a+b)%k=0 where

a=k*SOME_CONSTANT_1+REMAINDER_1 

b=k*SOME_CONSTANT_2+REMAINDER_2

then (REMAINDER_1 +REMAINDER_2 )%k will surely be 0

所以对于一个数组 (4,2,3,31,14,16,8) 和 k =5,如果你有一些类似下面的信息,你可以找出所有对的总和 %k =0

请注意,最底部的行包含从 0 到 k-1 的所有余数以及与之对应的所有数字。 现在您需要做的就是将两个指针移向对方,直到它们相遇。如果两个指针位置都有与之关联的数字,则它们的 sum%k 将为 0

要解决这个问题,您可以使用哈希表来跟踪您目前看到的所有剩余部分

  1. 创建哈希映射 Map
  2. 使用 0 到 k-1 预填充其键;
  3. 遍历数组并将每个数字的余数放入映射中,Key = 余数,并将实际数字放入列表中,
  4. 使用两个相互移动的指针迭代键集。和sum += listSizeAsPointedByPointer1 * listSizeAsPointedByPointer2

【讨论】:

    【解决方案3】:

    一些伪代码可以帮助您入门。它使用你说你尝试过的蛮力技术,但也许你的代码有问题?

    max = 1000000000
    numberPairs = 0
    for i = 1 to max - 2 do
        for j = i + 1 to max - 1 do
            if (i + j) mod k = 0 then
                numberPairs = numberPairs + 1
            end if
        end do
    end do
    

    【讨论】:

    • 这段代码耗时太长,能否建议优化算法
    【解决方案4】:

    一种方法是蛮力:

    int numPairs = 0;
    for (i = 0; i < 10e9; i++)
    {
        for (j = i+1; j < 10e9; j++)
        {
            int sum = i + j;
            if (sum % k == 0) numPairs++;
        }
     }
     return numPairs;
    

    我会留给你来优化它以提高性能。我至少可以想到一种方法来显着加快这一速度。

    【讨论】:

    • 这是我知道的蛮力技术。你能推荐其他技术吗?
    • 这段代码耗时太长,能否建议优化算法
    • 第一个优化:观察许多不同的数字对具有相同的和(例如:57 和 100、58 和 99、59 和 98、60 和 97 等)。您一次又一次地对相同的值进行求和和修改是在浪费时间。这里有一个提示:0 到 10e9 之间的两个整数有多少个和值?答案:2 x 10e9。您的问题已从 O(n^2) 减少到 O(n)!
    猜你喜欢
    • 2015-12-22
    • 2012-07-31
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-09
    • 2013-05-12
    • 2020-06-26
    相关资源
    最近更新 更多