#include<iostream.h>
int main()
{
int a[10]={1,2,3,5,2,3,1,5,3,1};
int i;
int c[10]={0};
for(i = 0 ; i < 10 ; i++)
c[a[i]]++;
for(i=0;i<10;i++)
cout<<i<<": "<<c[i]<<endl;
return 0;
}
算法的运行时间是O(n),但它占用了额外的O(n)空间。我能做得更好吗?
谢谢!
答案 0 :(得分:2)
取决于对你来说重要的事情 - 你可以创建一个算法,花费O(n ^ 2)时间,但是O(1)空间(使用两个循环,见下面的代码),但你不能在下面提高时间复杂度为O(n)。
for(i=0;i<10;i++) {
count = 0;
for(j=0;j<10;j++)
if (c[j] == i) count++;
cout<<i<<": "<<count<<endl;
}
O(1)空间的另一种可能性是数组的就地排序,然后遍历一次,使用就地合并排序应该具有时间复杂度O(n log n)。
答案 1 :(得分:0)
不,你不能。这是你能做的最好的事情。
答案 2 :(得分:0)
什么是“有效”?向我们展示性能要求和性能测量。然后我们可以告诉你它是否有效。在此之前,这是一个广泛的问题,有很多错误的答案,没有正确的答案。 到目前为止,答案是正确的,只有“有效”这个词意味着“尽可能快地运行”。
也许你有一台内存很少的快速电脑。
你总是可以让一段代码运行得更快或者使用更少的磁盘空间或更少的内存....如果它不够“高效”,我已经看到人们手工工具组装以使其更快。通常这是浪费时间和精力。优化尚未分析的代码是一个愚蠢的游戏。
答案 3 :(得分:0)
如果所有数字都在1到n的范围内,则可以在O(n)时间复杂度和O(1)空间复杂度中完成。
如果存在索引X和数组A使得A [X] = Y则将N加到索引Y处存在的值。所以A [Y]变为A [Y] =原始+ N.继续这个,值将是形式(原始+ KN),其中k> = 0.要检索我们可以做的原始元素(原始+ KN)%N,因为(x + kn)%n = x并且计数可以通过(原始+ KN)/ N。