【发布时间】:2016-09-27 13:51:13
【问题描述】:
给定一个像这样的金字塔:
0
1 2
3 4 5
6 7 8 9
...
并且给定金字塔的索引i 其中i 表示金字塔的ith 数字,有没有办法找到ith 元素所属的行的索引? (例如i = 6,7,8,9,它在第 3 行,从第 0 行开始)
【问题讨论】:
标签: math indexing computer-science
给定一个像这样的金字塔:
0
1 2
3 4 5
6 7 8 9
...
并且给定金字塔的索引i 其中i 表示金字塔的ith 数字,有没有办法找到ith 元素所属的行的索引? (例如i = 6,7,8,9,它在第 3 行,从第 0 行开始)
【问题讨论】:
标签: math indexing computer-science
我认为ith 元素属于nth 行,其中n 是n(n+1)/2 <= i < (n+1)(n+2)/2 的数量
例如,如果i = 6,那么n = 3,因为n(n+1)/2 <= 6
如果i = 8,那么n = 3,因为n(n+1)/2 <= 8
【讨论】:
行号和三角形数之间存在联系。 nth triangular number,表示为 Tn,由 Tn = n(n-1)/2 给出。前几个三角形数是 0、1、3、6、10、15 等,如果您注意到,每行的开头由第 n 个三角形数给出(它们来自这个三角形的事实是这个名字的来源。)
实际上,这里的目标是确定最大的 n,使得 Tn ≤ i。无需进行任何巧妙的数学运算,您只需计算 T0、T1、T2,即可在 O(√n) 时间内解决此问题,等等,直到你找到比我更大的东西。更好的是,您可以通过计算 T1, T2, T4, T8 等,直到你过冲,然后在你找到的范围上进行二进制搜索。
或者,我们可以尝试直接解决这个问题。假设我们想找到 n 的选择使得
n(n + 1) / 2 = i
展开,我们得到
n2 / 2 + n / 2 = i.
同样,
n2 / 2 + n / 2 - i = 0,
或者,更容易:
n2 + n - 2i = 0.
现在我们使用二次公式:
n = (-1 ± √(1 + 8i)) / 2
我们可以忽略的负根,所以我们想要的n值是
n = (-1 + √(1 + 8i)) / 2.
这个数字不一定是整数,所以要找到你想要的行,我们只需向下取整:
行 = ⌊(-1 + √(1 + 8i)) / 2⌋。
在代码中:
int row = int((-1 + sqrt(1 + 8 * i)) / 2);
让我们通过测试一下来确认它是否有效。 9去哪儿了?嗯,我们有
(-1 + √(1 + 72)) / 2 = (-1 + √73) / 2 = 3.77
向下取整,我们看到它在第 3 行 - 这是正确的!
再试一个,55去哪了?嗯,
(-1 + √(1 + 440)) / 2 = (√441 - 1) / 2 = 10
所以它应该在第 10 行。第十个三角形数是 T10 = 55,所以实际上,55 从该行开始。看起来它有效!
【讨论】:
我得到 row = math.floor (√(2i + 0.25) - 0.5) 其中 i 是你的号码
与上面的人基本相同,但我将 n2 + n 减少到 (n + 0.5)2 - 0.25
【讨论】: