找出一个数字属于哪个组?

时间:2013-02-05 09:45:45

标签: algorithm

我正在研究编码问题,作为其子部分,我遇到了这个问题:

我们给出一个数字x,我们将它平方,因此数字变为x ^ 2。现在我们有从1到x ^ 2的数字,例如: 如果number = 4; 然后 4 ^ 2 = 16

         1             ----->1
      2     3          ----->2
   4     5     6       ----->3
7     8     9    10    ----->4
  11    12    13       ----->5
     14    15          ----->6
        16             ----->7

现在给我一个数字说k,我需要告诉它属于哪个组。这里8属于第4组。

我认为是从1开始并将计数初始化为1并检查1 <8?如果是,则添加2比1(上一个总和),将计数增加到2并检查3 <8?如果是,则添加3到3(上一个总和),将计数增加到3并检查是否为6&lt; 8如果是,则添加4到6,将计数增加到4并检查10 <9?如果没有那么退出。 所以组号。算是4。

但是有没有比我的方法快的方法?

编辑1: 我忘了提到,在我的算法中,当计数达到给定数字时,在前面的示例中为4,那么我不应该添加5而是3.例如:

如果要搜索的数字是14,那么

1<14 yes then add 2

3<14 yes then add 3

6<14 yes then add 4

10<14 yes then add **3**  ---->here I need to add 3 instead of 5

13<14 yes then add **2**  ---->here I need to add 2 instead of 6

15<14 No so output count.

可以使用if条件添加3而不是5但是有任何方法可以根据x的值自动增加然后减少值(参见上面的示例以了解x指的是什么)

5 个答案:

答案 0 :(得分:5)

矩形的上半部分是三角形:

         1             ----->1
      2     3          ----->2
   4     5     6       ----->3
7     8     9    10    ----->4

,右侧(1,3,6,10)的数字称为triangular numbers。那里的反公式(在副标题“三角形根和三角数测试”下)可以用于你的问题:

def group(x, number):
    if number <= x^2 / 2 :
        return ceiling( (sqrt(8*number+1) - 1) / 2 )
    else:
        return 2*x - group(x, x^2+1-number)

答案 1 :(得分:4)

在上半部分,组i以数字i*(i+1)/2结尾。因此,假设您使用n获得了n <= x^2/2个数字,您需要找到i最小的i*(i+1)/2 <= n

i*i+i-2n = 0解决i收益:((sqrt(1+8n)-1/2) 例如。 n = 8i = ceil((sqrt(65)-1)/2) = 4

当然,案例n > x^2/2稍微复杂一些。

答案 2 :(得分:3)

首先假设为了简单起见, x <= n ^ 2/2 x 属于 t 组。然后:

t*(t-1)/2 < x <= t*(t+1)/2

从这里我们得到两个二次不等式:

t^2 - t - 2x < 0
t^2 + t - 2x >= 0

此处D=1+8x,因为t&gt; 0他们的共同解决方案是

t ∈ [ (-1-sqrt(D))/2; (1+sqrt(D))/2 )

现在记住t是一个整数(并且根据定义是唯一的),所以我们将得到解决方案公式:

t = floor( 1+sqrt(D))/2 )

这是案例 x&lt; = n ^ 2/2 的解决方案。在其他情况下,我们可以通过以下方式解决它:

  1. x:= n ^ 2 - x + 1
  2. 如上所述找到
  3. t:= n - t + 1
  4. 希望这有帮助。

答案 3 :(得分:2)

右上对角线上的数字是所谓的&#34;三角形数字&#34;,它们的公式为n(n+1)/2

右下对角线上的数字等于16减去三角形数字,它们的公式为x^2 - (2*x-n-1)(2*x-n)/2

所以给定kx,您正在寻找最少n,以使公式大于或等于k,选择哪个公式根据{{​​1}}是大于还是小于k三角形数x(在本例中为10)。由于两个函数都是单调的(总是增加),你可以通过在浮点中求解x(x+1)/2(使用二次公式)的二次方程式然后向上舍入到下一个整数(所谓的&#34)来做到这一点。 ;天花板&#34;。)

为了解释浮点不准确性而不引入太多复杂性,您应该使用整数运算来检查结果。浮点计算可能会略微超调或低于正确的结果,并舍入到错误的整数值。对于较小的数字,在最差情况下它不会超过1,因此检测和纠正这一问题的代码很简单,只需将n与通过放置k得到的值进行比较将结果导入公式和n两侧的值。

答案 4 :(得分:1)

首先,您需要观察xth行正好是中间行,并且其中包含x个元素。那么这一特定行中的元素是什么 - 它们来自[x(x+1)/2-x, x(x+1)/2]。所以算法是这样的:

  1. 检查要搜索的号码是否在中间行,小于或大于该行。
  2. 如果在中间行打印x。
  3. 如果小于中间行,则需要观察所有行以三角形结尾。您可以使用公式ceil((sqrt(8x+1)-1)/2)来获取确切的行。
  4. 如果数字大于中间行,那么你可以做的就是将下三角形想象成这样:

    6 5 4

    3 2

    1

  5. 也就是说,所有数字都等于x^2+1-that number。所以现在您将使用上面的公式本身搜索下三角形中的x^2+1-number to be searched。这会以倒置的形式给出行号。请将该数字变为k。然后,正确形式的值为x-1+k+1。最后将x添加到值以将答案移至下三角形。因此答案变为2x+k

    这是问题的O(1)解决方案。