关于时间复杂度的几个问题
原创翻译加学习笔记,方便国人学习算法知识!
原文链接http://www.geeksforgeeks.org/a-time-complexity-question/
fun()的时间复杂度是多少?假设log(x) 是以2为底的
void fun() { int i, j; for (i=1; i<=n; i++) for (j=1; j<=log(i); j++) printf("GeeksforGeeks"); }
这份函数的时间复杂度可以写作Θ(log 1) + Θ(log 2) + Θ(log 3) + . . . . + Θ(log n) = Θ(log n!)。
当n是一个很大的数时 log n! 就等于 nlogn 所以说Θ (log n!) = Θ(n log n) 那么fun()的时间复杂度就是 Θ (nlog n)。
可以用斯特灵公式来证明Θ(log n!) = Θ(n log n)
https://en.wikipedia.org/wiki/Stirling%27s_approximation
第二个问题
void fun(int n) { int j = 1, i = 0; while (i < n) { // Some O(1) task i = i + j; j++; } }
循环计数器是按照1,2,3,4 直到i>=n
i的值 是x(x+1)/2, x是循环的次数,所以循环x次, x(x+1)/2 所以时间复杂度是Θ(√n)
第三个问题
void fun(int n, int k) { for (int i=1; i<=n; i++) { int p = pow(i, k); for (int j=1; j<=p; j++) { // Some O(1) work } } }
时间复杂度可以写作1k+2k+3k+...+nk
k=1 Sum = 1 + 2 + 3 ... n = n(n+1)/2 = n^2 + n/2 k=2 Sum = 1^2 + 2^2 + 3^2 + ... n^2. = n(n+1)(2n+1)/6 = n^3/3 + n^2/2 + n/6 k=3 Sum = 1^3 + 2^3 + 3^3 + ... n^3. = n^2(n+1)^2/4 = n^4/4 + n^3/2 + n^2/4
So the time complexity is Θ(n(k+1) / (k+1))
第四个问题:
这个函数是计算2维数组的和,忽略编译器的优化,哪一种实现更好呢
// Function 1 int fun1(int arr[R][C]) { int sum = 0; for (int i=0; i<R; i++) for (int j=0; j<C; j++) sum += arr[i][j]; } // Function 2 int fun2(int arr[R][C]) { int sum = 0; for (int j=0; j<C; j++) for (int i=0; i<R; i++) sum += arr[i][j]; }
在C/C++里, 元素是按照行优先的顺序存储的(一行中的元素是连续存储在内存的),所以第一个实现比较好