假设next()
是生成此系列的函数:
8
9
16
25
27
32
36
49
64
81
哪个是
i=2,3,....
j=2,3,....
f(n) = minimum( pow(i,j) ) && f(n) > f(n-1)
我可以拿出这个O(n)代码。是否有O(1)或O(lg n)解决方案?
int m =2, n = 2;
int last =4;
void next() {
int a=m+1,b=n+1;
long t = pow(a,b);
int ma = max(m,n);
//cout<<" max = "<<ma<<endl;
for(int i=2;i<=ma+1;++i){
for(int j=2;j<=ma+1;++j){
if(pow(i,j) > last && pow(i,j) <= t) {
a=i,b=j;
t = pow(i,j);
}
}
}
if(a>m) m=a;
if(b>n) n=b;
last = t;
//cout<<"\t"<<a<<"\t"<<b<<"\t"<<pow(a,b)<<endl;
cout<<" \t"<<pow(a,b)<<endl;
return;
}
}
注意: 当我提到复杂性时,我只谈了一次对next()的调用。 2.缓存当然会有所帮助,但是我们可以考虑使用lg-n空间进行缓存吗? 哎呀,缓存一切都更快。 :) 3.如果存在O(lg-n)的解决方案,我不知道恒定空间的复杂性,只是我的预感可能会有......
答案 0 :(得分:1)
示例python代码,显然不完美,但确实显示了如何进行延迟迭代。内存使用量为O(服务项目数),对于时间,乘以该日志。
import heapq
def power_seq(min_b, min_p):
heap = []
in_heap_table = {}
cur_b, cur_p = min_b, min_p
heapq.heappush(heap, (power_value(cur_b, cur_p), cur_b, cur_p))
in_heap_table[power_value(cur_b, cur_p)] = True
while True:
power, cur_b, cur_p = heapq.heappop(heap)
yield power,cur_b, cur_p
new_b = cur_b + 1
new_p = cur_p + 1
if power_value(new_b, cur_p) not in in_heap_table:
heapq.heappush(heap, (power_value(new_b, cur_p), new_b, cur_p))
in_heap_table[power_value(new_b, cur_p)] = True
if power_value(cur_b, new_p) not in in_heap_table:
heapq.heappush(heap, (power_value(cur_b, new_p), cur_b, new_p))
in_heap_table[power_value(cur_b, new_p)] = True
# Can be made O(log p) if we want.
def power_value(b,p):
power = 1
while p >= 1:
power = power*b
p = p-1
return power
def main():
count = 0
for tup in power_seq(2,2):
print tup
count += 1
if count > 30:
break
if __name__ == "__main__":
main()
答案 1 :(得分:0)
(我不知道你是否知道你的问题是关于一系列完美数字的事实)
可能更快的强力算法: 在给定范围内生成所有可能的完美幂并将它们插入到排序列表中。但是,我不知道你有多少重复。绝对需要比你的方法更多的内存,但你没有给出任何限制:)
答案 2 :(得分:0)
我想象的方法是通过生成器对所有功率结果的排序列表进行某种惰性构造。
想象一下x ^ y结果的无穷无尽的领域 - x在一个方向上,y在另一个方向上。现在想象一条从2 ^ 2开始的路径(为简单起见,我们称其为1),从东到3 ^ 2,从西南到2 ^ 3,从南到2 ^ 4,东北两次,一个东,西南三次,一个南...等等,对角曲折并向外移动。
当你在所有x ^ ys上移动这个之字形路径时,将它们添加到自动排序的集合中,总共为O(nlogn)。但是,我们很懒,想尽快停下来。
当你被要求获得第n个最大的力量时,做zig-zags并建立集合,跟踪每个zig-zag产生的最低值。如果最低值大于当前列表中第n个位置下方列表中的所有内容,我们知道我们永远不会在列表中插入一个更低的数字来改变我们返回的结果 - 所以我们将其返回。 / p>
此外,如果您被要求获得第n个最大功率,您可以立即检查最低值是否足够低以更改值,如果不是则立即返回。
这种算法不是最理想的,因为功率在一个方向上比在另一个方向上增长得更快 - 因此偏向于在增长较慢的方向上覆盖更多值的路径比快速增长的方向需要搜索更少的值以返回第n个最大的力量。