为了性能,在O(n ^ 2)算法中,我希望将复杂度降低两倍。基本上,我有这种形状的结构:
0 1 2 3 4 5
----------------------
0 | 1
1, 2 | 2
3, 4, 5 | 3
6, 7, 8, 9 | 4
10, 11, 12, 13, 14 | 5
15, 16, 17, 18, 19, 20| 6
因此我创建了一个大小为((1+n)*n/2)
的向量 - 显然是算术和。问题是我现在需要来回计算每个位置。例如,如果我想计算列2
和行5
中的位置,我可以像这样计算:
int get_position(int x, int y)
{
int smaller = min(x, y);
int greater = max(x, y);
return ((1 + greater) * greater / 2) - greater + smaller;
}
问题是:如何计算回来的方式?换句话说,例如来自位置编号。 17
我想获得2
和6
。
或者,也许在C ++中有更好的方法可以做到这一点? (某些结构会让事情变得简单)
修改 我正在寻找一种在O(1)中计算的方法。它存在吗?
答案 0 :(得分:5)
是的,确实存在O(1)解决方案。
数学上,更大的指数是:
i = [sqrt(2n + 1/4) + 1/2]
(方括号“[]
”表示截断为整数。)
但是,在浮点数上正确计算它可能很困难。
然后是较小的索引:
j = n - i*(i-1) / 2
答案 1 :(得分:0)
这不是N平方,因为我们可以消除整个阵列的下降,而不是使用枢轴搜索正确的阵列。
首先,我们检查每个阵列的第一个数字并等待N到达[0]和到达+ 1 [0]之间。
之后,您可以使用二进制搜索算法在数组中查找正确的数字。
二进制搜索是log n,我不能随便告诉你第一部分的运行时间,但我猜测log n。因此,此操作可以在log n time