简体   繁体   English

求和小于 O(N)

[英]Finding sum in less than O(N)

Question: In less O(n) find a number K in sequence 1,2,3...N such that sum of 1,2,3...K is exactly half of sum of 1,2,3..N问题:在更少的 O(n) 中找到一个数字 K 序列 1,2,3...N 使得 1,2,3...K 的总和正好是 1,2,3..N 的总和的一半

Maths: I know that the sum of the sequence 1,2,3....N is N(N+1)/2 .数学:我知道序列 1,2,3....N 的总和是N(N+1)/2

Therefore our task is to find K such that: K(K+1) = 1/2 * (N)(N+1)/2 if such a K exists.因此我们的任务是找到 K 使得: K(K+1) = 1/2 * (N)(N+1)/2如果这样的 K 存在。

Pseudo-Code:伪代码:

sum1 = n(n+1)/2
sum2 = 0

for(i=1;i<n;i++)
{
    sum2 += i;
    if(sum2 == sum1)
    {
        index = i
        break;
    }
}

Problem: The solution is O(n) but I need better such as O(n), O(log(n))...问题:解决方案是O(n)但我需要更好的,例如O(n)、O(log(n))...

You're close with your equation, but you dropped the divide by 2 from the K side.你的方程很接近,但是你把 K 边的除以 2 去掉了。 You actually want你其实想要

K * (K + 1) / 2 = N * (N + 1) / (2 * 2)

Or或者

2 * K * (K + 1) = N * (N + 1)

Plugging that into wolfram alpha gives the real solutions:将其插入 wolfram alpha 给出了真正的解决方案:

K = 1/2 * (-sqrt(2N^2 + 2N + 1) - 1)
K = 1/2 * (sqrt(2N^2 + 2N + 1) - 1)

Since you probably don't want the negative value, the second equation is what you're looking for.由于您可能不想要负值,因此第二个等式就是您要寻找的。 That should be an O(1) solution.那应该是一个 O(1) 解决方案。

The other answers show the analytical solutions of the equation其他答案显示了方程的解析解

k * (k + 1) = n * (n + 1) / 2            Where n is given

The OP needs k to be a whole number, though, and such value may not exist for every chosen n .但是,OP 需要k是一个整数,并且对于每个选择的n可能不存在这样的值。

We can adapt the Newton's method to solve this equation using only integer arithmetics.我们可以采用牛顿法仅使用整数算法来求解这个方程。

sum_n =  n * (n + 1) / 2
k = n
repeat indefinitely         // It usually needs only a few iterations, it's O(log(n))
    f_k = k * (k + 1)
    if  f_k == sum_n
        k is the solution, exit
    if  f_k < sum_n
        there's no k, exit 
    k_n = (f_k - sum_n) / (2 * k + 1)   // Newton step: f(k)/f'(k) 
    if  k_n == 0
        k_n = 1   // Avoid inifinite loop
    k = k - k_n;

Here there is a C++ implementation.这里有一个 C++ 实现。


We can find all the pairs ( n , k ) that satisfy the equation for 0 < k < nN adapting the algorithm posted in the question.我们可以找到满足 0 < k < nN的方程的所有对 ( n , k ) 以适应问题中发布的算法。

n = 1                        // This algorithm compares 2 * k * (k + 1) and n * (n + 1)
sum_n = 1                    // It finds all the pairs (n, k) where 0 < n ≤ N in O(N)
sum_2k = 1
for every n <= N             // Note that n / k → sqrt(2) when n → ∞
    while  sum_n < sum_2k
        n = n + 1            // This inner loop requires a couple of iterations,
        sum_n = sum_n + n    // at most.
   
    if ( sum_n == sum_2k )
        print n and k
   
    k = k + 1
    sum_2k = sum_2k + 2 * k

Here there is an implementation in C++ that can find the first pairs where N < 200,000,000:这里有一个 C++ 实现,可以找到N < 200,000,000 的第一对:

           N           K           K * (K + 1)
----------------------------------------------
           3           2                     6
          20          14                   210
         119          84                  7140
         696         492                242556
        4059        2870               8239770
       23660       16730             279909630
      137903       97512            9508687656
      803760      568344          323015470680
     4684659     3312554        10973017315470
    27304196    19306982       372759573255306
   159140519   112529340     12662852473364940

Of course it becomes impractical for too large values and eventually overflows.当然,它对于太大的值变得不切实际并最终溢出。

Besides, there's a far better way to find all those pairs (have you noticed the patterns in the sequences of the last digits?).此外,还有一种更好的方法可以找到所有这些对(您是否注意到最后一位数字序列中的模式?)。

We can start by manipulating this Diophantine equation :我们可以从操纵这个丢番图方程开始

2k(k + 1) = n(n + 1)
                                   introducing   u = n + 1   →   n = u - 1
                                                 v = k + 1       k = v - 1
2(v - 1)v = (u - 1)u
2(v2 - v) = u2 + u
2(4v2 - 4v) = 4u2 + 4u
2(4v2 - 4v) + 2 = 4u2 - 4u + 2
2(4v2 - 4v + 1) = (4u2 - 4u + 1) + 1
2(2v - 1)2 = (2u - 1)2 + 1
                                 substituting   x = 2u - 1   →   u = (x + 1)/2
                                                y = 2v - 1       v = (y + 1)/2

2y2 = x2 + 1
x2 - 2y2 = -1

Which is the negative Pell's equation for 2.这是 2 的负佩尔方程

It's easy to find its fundamental solutions by inspection, x 1 = 1 and y 1 = 1. Those would correspond to n = k = 0, a solution of the original Diophantine equation, but not of the original problem (I'm ignoring the sums of 0 terms).通过检查很容易找到它的基本解, x 1 = 1 和y 1 = 1。它们对应于n = k = 0,这是原始丢番图方程的解,但不是原始问题的解(我忽略了0 项的总和)。

Once those are known, we can calculate all the other ones with two simple recurrence relations一旦知道这些, 我们就可以用两个简单的递推关系计算所有其他的

xi+1 = xi + 2yi
yi+1 = yi + xi

Note that we need to "skip" the even y s as they would lead to non integer solutions.请注意,我们需要“跳过”偶数y ,因为它们会导致非整数解。 So we can directly use theese所以我们可以直接使用theese

xi+2 = 3xi + 4yi   →   ui+1 = 3ui + 4vi - 3  →   ni+1 = 3ni + 4ki + 3
yi+2 = 2xi + 3yi       vi+1 = 2ui + 3vi - 2      ki+1 = 2ni + 3ki + 2

Summing up:加起来:

                    n                         k
-----------------------------------------------
3* 0 + 4* 0 + 3 =   3      2* 0 + 3* 0 + 2 =  2  
3* 3 + 4* 2 + 3 =  20      2* 3 + 3* 2 + 2 = 14  
3*20 + 4*14 + 3 = 119      2*20 + 3*14 + 2 = 84  
...

It seems that the problem is asking to solve the diophantine equation似乎问题是要求解决丢番图方程

2K(K+1) = N(N+1).

By inspection, K=2 , N=3 is a solution !通过检查, K=2N=3是一个解决方案!


Note that technically this is an O(1) problem, because N has a finite value and does not vary (and if no solution exists, the dependency on N is even meanignless).请注意,从技术上讲,这是一个 O(1) 问题,因为 N 具有有限值并且不会变化(如果不存在解决方案,则对 N 的依赖甚至是无意义的)。

The condition you have is that the sum of 1..N is twice the sum of 1..K你的条件是 1..N 的总和是 1..K 总和的两倍

So you have N(N+1) = 2K(K+1) or K^2 + K - (N^2 + N) / 2 = 0所以你有N(N+1) = 2K(K+1)K^2 + K - (N^2 + N) / 2 = 0

Which means K = (-1 +/- sqrt(1 + 2(N^2 + N)))/2这意味着K = (-1 +/- sqrt(1 + 2(N^2 + N)))/2

Which is O(1)这是 O(1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 查找长度为n的列表的k个元素,它们在O(nlogk)时间之内的总和小于t - Finding k elements of length-n list that sum to less than t in O(nlogk) time 从排序数组中查找小于O(n)的唯一数字 - Finding unique numbers from sorted array in less than O(n) 在不到O(n)的时间内找到交换元素? - Finding swapped elements in less than O(n) time? 在小于O(n)比较中找到3个最小元素的时间复杂度 - Time complexity of finding 3 smallest elements in less than O(n) comparisons 稀疏数组中某个范围的总和小于O(n)吗? - Sum between a range in a sparsely populated array in less than O(n)? 3SUM 问题(寻找三元组)优于 O(n^2) - 3SUM problem (finding triplets) in better than O(n^2) 在小于O(n ^ 2m)的时间内找到最小汉明距离 - Finding the minimum Hamming distance in less than O(n^2m) time 坚持如何使这个回文对找到 function 小于 O(N^2) - Stuck on how to make this palindrome pairs finding function be less than O(N^2) 是否有一种算法可以找到总和小于给定 K 的子列表的数量? 优于 O(N^2) - Is there an algorithm for finding amount of sublists whose sum is smaller than given K? Better than O(N^2) 对于小于和等于O(n2)的负数和正数,子数组总和等于k - Subarray sum equal to k for negative and positive numbers in less than O(n2)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM