我有这段代码:
int fun(int n)
{
int count = 0;
for (int i = n; i > 0; i /= 2)
for (int j = 0; j < i; j++)
count += 1;
return count;
}
此代码的时间复杂度可以被视为O(n)
,因为O(n+n/2+n/4+...) = O(n)
按照这种逻辑,此片段的时间复杂度也可以被认为是O(n)
:
for(i = 1; i < n; i *= 2)
//O(1) statements
自O(1+2+4+..+n/4+n/2) = O(n)
以来。但由于循环运行log(n)
次,因此它也可以log(n)
。
为什么前者不是:log(n)
次外圈 * log(n)
倍于内圈,log(n)log(n)
我做错了什么?
答案 0 :(得分:2)
第一个片段的外部循环执行O(log n)
次,每次迭代内部循环执行O(i)
次。如果您对n / 2^k
表单中的任意数量的术语求和,那么您将获得O(n)
。
第二段代码具有O(log n)
次O(1)
次操作的迭代次数,对数量的常数之和仍为对数。
答案 1 :(得分:1)
第二个的时间复杂度不应计算为一系列O(1+2+4+..+n/4+n/2) = O(n)
,因为不该系列。
注意第一个。它被计算为一个系列,因为一个计算内部for
循环执行的次数,然后添加所有这些(系列)以获得最终的时间复杂度。
当i=n
内部for
循环执行n
次时
当i=(n/2)
内部for
循环执行n/2
次时
当i=(n/4)
内部for
循环执行n/4
次时
等等..
但是在第二个中,没有要添加的系列。它只是一个公式(2^x) = n
,其评估结果为x = logn
。
(2^x) = n
此公式可以通过注意i
以1
开头,当它变为2
时获得2
直到达到n
2
。
因此,需要了解2
需要乘以n
到达(2^x) = n
的次数。
因此,公式x
,然后解决$sample = 'UNITED STATES OF AMERICA';
function convert_str($str)
{
$except = array('of', 'in', 'is'); // Words you dont want to convert
$str= strtolower($str); // apply strtolower to all
return (in_array($str, $except)) ? $str : ucwords($str); // apply ucwords conditionally
}
$temp = explode(' ', $sample); // explode by space
$new_temp = array_map('convert_str', $temp); // apply the function to every element
echo implode(' ', $new_temp); // implode again
。
答案 2 :(得分:1)
在第一个示例中,您的循环中没有O(1)语句,因为您有for (int j = 0; j < i; j++) count += 1
。如果在第二个示例中放置了第一个示例的相同内循环,则会回到相同的复杂程度。第一个循环不是O(n*log(n))
;这很容易证明,因为您可以在O(2n)
中找到相当于O(n)
的上限。