大 O - O(log(n)) 代码示例
Posted
技术标签:
【中文标题】大 O - O(log(n)) 代码示例【英文标题】:Big O - O(log(n)) code example 【发布时间】:2013-06-11 22:45:24 【问题描述】:就像大 O 符号“O(1)”可以描述以下代码:
O(1):
for (int i = 0; i < 10; i++)
// do stuff
a[i] = INT;
O(n):
for (int i = 0; i < n; i++)
// do stuff
a[i] = INT;
O(n^2):
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
// do stuff
a[i][j] = INT;
O(log(n)) 可以描述什么代码?
另一个问题:
对于“大 O 问题”(当获取大量数据作为输入时该怎么办)有哪些解决方案?【问题讨论】:
O(log n) 通常是在算法分而治之的时候,比如二分搜索或类似的。 这是一个实用的(编码测试)示例leetcode.com/problems/find-peak-element => 查看问题和解决方案 【参考方案1】:经典例子:
while (x > 0)
x /= 2;
这将是:
Iteration | x
----------+-------
0 | x
1 | x/2
2 | x/4
... | ...
... | ...
k | x/2^k
2k = x → 两边应用对数 → k = log(x)
【讨论】:
伟大而简单的例子,正是我想要的!谢谢你:) 我错过了你得到 2^k = x 的那一刻,而它曾经是 x/2^k ? 1 是最后一次迭代。所以我想知道在哪一点上这将被评估为 1。 有史以来最好的解释。非常感谢。 @DanielGurinov,x/2^k 的除法最终会得到 1。等式这会给你, 1=x/2^k ,相当于, x=2^k ,关于应用日志。当 b 的 y 次方等于 x 时: b^y = x ;在这种情况下 2^y=x 那么 x 的以 b 为底的对数等于 y: logb(x) = y ;在这种情况下,k = log(x) 意味着 log base 2【参考方案2】:带有 for 循环的最简单代码,可用于表示:
O(1):
function O_1(i)
// console.log(i);
return 1
O(n):
function O_N(n)
count = 0;
for (i = 0; i < n; i++)
// console.log(i);
count++;
return count
O(n²):
function O_N2(n)
count = 0;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
// console.log(i, j);
count++;
return count
O(Log2(n)):
function O_LOG_2(n)
count = 0;
for (var i = 1; i < n; i = i * 2)
count++;
return count
O(Sqrt(n)):
function O_SQRT(n)
count = 0;
for (var i = 1; i * i < n; i++)
// console.log(i);
count++;
return count
【讨论】:
【参考方案3】:根据定义,log(n)(我的意思是以 2 为底的对数,但底数实际上并不重要)是您必须乘以 2 才能得到 n 的次数。所以,O(log(n)) 代码示例是:
i = 1
while(i < n)
i = i * 2
// maybe doing addition O(1) code
在实际代码示例中,您可以在二进制搜索、平衡二进制搜索树、许多递归算法、优先级队列中遇到 O(log(n))。
【讨论】:
【参考方案4】:对于 O(logn),请查看任何涉及分治策略的代码 示例:合并排序和快速排序(在这些情况下,预计运行时间为 O(nlogn))
【讨论】:
【参考方案5】:二分搜索是一个例子 O(log(n))。 http://en.wikipedia.org/wiki/Binary_search_algorithm.
【讨论】:
【参考方案6】:可能值得强调的是,您描述的较低复杂度算法是较高复杂度算法的子集。换句话说,
for (int i = 0; i < 10; i++)
// do stuff
a[i] = INT;
在 O(1) 中,但也在 O(n)、O(n²) 中,如果你想聪明一点,O(log(n))。为什么?因为所有的恒定时间算法都受到一些线性、二次等函数的限制。
对于“大 O 问题”有哪些解决方案(当获取大量数据作为输入时该怎么做)?
这个问题对我来说没有多大意义。 “大量数据”是相当随意的。不过,请记住,大 O 并不是时间复杂度的唯一衡量标准。除了测量最坏情况的时间复杂度外,我们还可以检查最佳情况和平均情况,尽管计算起来可能有点棘手。
【讨论】:
【参考方案7】:在二分搜索的情况下,您试图找到最大的迭代次数,因此搜索空间可以分成两半的最大次数。这是通过重复将搜索空间的大小 n 除以 2 直到达到 1 来实现的。
让我们给出标签 x 需要将 n 除以 2 的次数。由于除以 2,x 次等于除以 2^x,因此您最终必须求解这个等式:
n/2^x = 1,变成n = 2^x,
所以使用对数,x = log(n),所以二进制搜索的 BIG - O 是 O(log(n))
重申一下:x 是在将大小为 n 的空间缩小到大小为 1 之前,您可以将其分成两半的次数。
http://www.quora.com/How-would-you-explain-O-log-n-in-algorithms-to-1st-year-undergrad-student
【讨论】:
以上是关于大 O - O(log(n)) 代码示例的主要内容,如果未能解决你的问题,请参考以下文章