For big-O proof , show that there exists constants c, and n 0 n_0 n 0 such that f ( n ) ≤ c ∗ g ( n ) f(n) ≤ c*g(n) f ( n ) ≤ c ∗ g ( n ) for every n ≥ n 0 n ≥ n_0 n ≥ n 0 , then f ( n ) = O ( g ( n ) ) f(n) = O(g(n)) f ( n ) = O ( g ( n )) .
For big-Θ proof , show that there exists constants c 1 c_1 c 1 , c 2 c_2 c 2 , and n 0 n_0 n 0 such that c 1 ∗ g ( n ) ≤ f ( n ) ≤ c 2 ∗ g ( n ) c1*g(n) ≤ f(n) ≤ c2*g(n) c 1 ∗ g ( n ) ≤ f ( n ) ≤ c 2 ∗ g ( n ) for every n ≥ n 0 n ≥ n_0 n ≥ n 0 , then f ( n ) = Θ ( g ( n ) ) f(n) = Θ(g(n)) f ( n ) = Θ ( g ( n )) .
Use the **formal proof of big-O and big-**Θ in order to show the following (10 minutes): a) 𝑛 2 + 5 𝑛 − 2 𝑛^2 + 5𝑛 − 2 n 2 + 5 n − 2 is 𝑂 ( 𝑛 2 ) 𝑂(𝑛^2) O ( n 2 )
b) n 2 − 1 n + 1 \frac{n^2-1}{n+1} n + 1 n 2 − 1 is O ( n ) O(n) O ( n )
C) 5 n 2 − 3 n + 2 \sqrt{5n^2 - 3n + 2} 5 n 2 − 3 n + 2
State True or False and explain why for the following (10 minutes): a) 8 n 2 ( n ) 8n^2(\sqrt{n}) 8 n 2 ( n ) is O ( n 3 ) O(n^3) O ( n 3 )
b) 8 𝑛 2 ( 𝑛 ) 8𝑛^2(\sqrt{𝑛}) 8 n 2 ( n ) is Θ ( 𝑛 3 ) Θ(𝑛^3) Θ ( n 3 )
Sort the following 18 functions in an increasing asymptotic order and w r i t e < o r < = b e t w e e n write < or <= between w r i t e < or <= b e tw ee n each two subsequent functions to indicate if the first is asymptotically less than or asymptotically equivalent to the second function respectively. For example, if you were to sort:
𝑓 1 ( 𝑛 ) = 𝑛 𝑓_1(𝑛) = 𝑛 f 1 ( n ) = n , 𝑓 2 ( 𝑛 ) = 𝑙 𝑜 𝑔 ( 𝑛 ) 𝑓_2(𝑛) = 𝑙𝑜𝑔(𝑛) f 2 ( n ) = l o g ( n ) , 𝑓 3 ( 𝑛 ) = 3 𝑛 𝑓_3(𝑛) = 3𝑛 f 3 ( n ) = 3 n , 𝑓 4 ( 𝑛 ) = 𝑛 2 𝑓_4(𝑛) = 𝑛^2 f 4 ( n ) = n 2 ,
your answer could be 𝑙 𝑜 𝑔 ( 𝑛 ) < ( 𝑛 < = 3 𝑛 ) < 𝑛 2 𝑙𝑜𝑔(𝑛) < ( 𝑛 <= 3𝑛) < 𝑛^2 l o g ( n ) < ( n <= 3 n ) < n 2
Hint: Try grouping the functions like so: linear, quadratic, cubic, exponential ... etc
𝑓 1 ( 𝑛 ) = 𝑛 𝑓_1(𝑛) = 𝑛 f 1 ( n ) = n
𝑓 2 ( 𝑛 ) = 500 𝑛 𝑓_2(𝑛) = 500𝑛 f 2 ( n ) = 500 n
𝑓 3 ( 𝑛 ) = 𝑛 𝑓_3(𝑛) = \sqrt{𝑛} f 3 ( n ) = n
𝑓 4 ( 𝑛 ) = 𝑙 𝑜 𝑔 ( 𝑛 ) 𝑓_4(𝑛) = 𝑙𝑜𝑔(\sqrt{𝑛}) f 4 ( n ) = l o g ( n )
𝑓 5 ( 𝑛 ) = 𝑙 𝑜 𝑔 ( 𝑛 ) 𝑓_5(𝑛) = \sqrt{𝑙𝑜𝑔(𝑛)} f 5 ( n ) = l o g ( n )
𝑓 6 ( 𝑛 ) = 1 𝑓_6(𝑛) = 1 f 6 ( n ) = 1
𝑓 7 ( 𝑛 ) = 3 𝑛 𝑓_7(𝑛) = 3^𝑛 f 7 ( n ) = 3 n
𝑓 8 ( 𝑛 ) = 𝑛 ⋅ 𝑙 𝑜 𝑔 ( 𝑛 ) 𝑓_8(𝑛) = 𝑛 · 𝑙𝑜𝑔(𝑛) f 8 ( n ) = n ⋅ l o g ( n )
𝑓 9 ( 𝑛 ) = n l o g ( n ) 𝑓_9(𝑛) = \frac{n}{log(n)} f 9 ( n ) = l o g ( n ) n
𝑓 10 ( 𝑛 ) = 700 𝑓_{10}(𝑛) = 700 f 10 ( n ) = 700
𝑓 11 ( 𝑛 ) = 𝑙 𝑜 𝑔 ( 𝑛 ) 𝑓_{11}(𝑛) = 𝑙𝑜𝑔(𝑛) f 11 ( n ) = l o g ( n )
𝑓 12 ( 𝑛 ) = 9 n 𝑓_{12}(𝑛) = \sqrt{9n} f 12 ( n ) = 9 n
𝑓 13 ( 𝑛 ) = 2 𝑛 𝑓_{13}(𝑛) = 2^𝑛 f 13 ( n ) = 2 n
𝑓 14 ( 𝑛 ) = 𝑛 2 𝑓_{14}(𝑛) = 𝑛^2 f 14 ( n ) = n 2
𝑓 15 ( 𝑛 ) = n 3 𝑓_{15}(𝑛) = n^3 f 15 ( n ) = n 3
𝑓 16 ( 𝑛 ) = n 3 𝑓_{16}(𝑛) = \frac{n}{3} f 16 ( n ) = 3 n
𝑓 17 ( 𝑛 ) = n 3 𝑓_{17}(𝑛) = \sqrt{n^3} f 17 ( n ) = n 3
𝑓 18 ( 𝑛 ) = 𝑛 ! 𝑓_{18}(𝑛) = 𝑛! f 18 ( n ) = n !
zh 首先,我们将这些函数按照它们的渐近增长率分类,然后进行排序。为了简化,我会跳过计算的细节。
以下是排序:
常数时间:f 6 ( n ) = 1 f_6(n) = 1 f 6 ( n ) = 1 和 f 10 ( n ) = 700 f_{10}(n) = 700 f 10 ( n ) = 700 。在这两个之间,f 6 ( n ) f_6(n) f 6 ( n ) 明显比 f 10 ( n ) f_{10}(n) f 10 ( n ) 小。 对数时间:f 11 ( n ) = l o g ( n ) f_{11}(n) = log(n) f 11 ( n ) = l o g ( n ) 和 f 4 ( n ) = l o g ( n ) f_4(n) = log(\sqrt{n}) f 4 ( n ) = l o g ( n ) 。我们知道 l o g ( n ) = 0.5 × l o g ( n ) log(\sqrt{n}) = 0.5 \times log(n) l o g ( n ) = 0.5 × l o g ( n ) ,所以 f 4 f_4 f 4 是较小的。 次线性时间:f 5 ( n ) = l o g ( n ) f_5(n) = \sqrt{log(n)} f 5 ( n ) = l o g ( n ) 线性时间中的一些函数:f 1 ( n ) = n f_1(n) = n f 1 ( n ) = n , f 2 ( n ) = 500 n f_2(n) = 500n f 2 ( n ) = 500 n , 和 f 16 ( n ) = n 3 f_{16}(n) = \frac{n}{3} f 16 ( n ) = 3 n 几个其他线性和次线性时间的函数:f 3 ( n ) = n f_3(n) = \sqrt{n} f 3 ( n ) = n , f 12 ( n ) = 9 n f_{12}(n) = \sqrt{9n} f 12 ( n ) = 9 n 。f 12 f_{12} f 12 可以简化为 3 n 3\sqrt{n} 3 n ,所以 f 3 ( n ) f_3(n) f 3 ( n ) 是较小的。 线性对数时间:f 8 ( n ) = n ⋅ l o g ( n ) f_8(n) = n \cdot log(n) f 8 ( n ) = n ⋅ l o g ( n ) 次线性时间中的一个函数:f 9 ( n ) = n l o g ( n ) f_9(n) = \frac{n}{log(n)} f 9 ( n ) = l o g ( n ) n 平方时间:f 14 ( n ) = n 2 f_{14}(n) = n^2 f 14 ( n ) = n 2 立方和次立方时间:f 15 ( n ) = n 3 f_{15}(n) = n^3 f 15 ( n ) = n 3 和 f 17 ( n ) = n 3 f_{17}(n) = \sqrt{n^3} f 17 ( n ) = n 3 。f 17 f_{17} f 17 可以简化为 n 1.5 n^{1.5} n 1.5 ,所以 f 17 ( n ) f_{17}(n) f 17 ( n ) 是较小的。 指数时间:f 13 ( n ) = 2 n f_{13}(n) = 2^n f 13 ( n ) = 2 n 和 f 7 ( n ) = 3 n f_7(n) = 3^n f 7 ( n ) = 3 n 。f 13 ( n ) f_{13}(n) f 13 ( n ) 是较小的。 阶乘时间:f 18 ( n ) = n ! f_{18}(n) = n! f 18 ( n ) = n ! 是所有函数中增长最快的。 所以,最终的排序为:
f 6 ( n ) < = f 10 ( n ) < f 4 ( n ) < = f 11 ( n ) < f 5 ( n ) < f 16 ( n ) < = f 1 ( n ) < = f 2 ( n ) < f 3 ( n ) < = f 12 ( n ) < f 8 ( n ) < f 9 ( n ) < f 14 ( n ) < f 17 ( n ) < f 15 ( n ) < f 13 ( n ) < f 7 ( n ) < f 18 ( n ) f_6(n) <= f_{10}(n) < f_4(n) <= f_{11}(n) < f_5(n) < f_{16}(n) <= f_1(n) <= f_2(n) < f_3(n) <= f_{12}(n) < f_8(n) < f_9(n) < f_{14}(n) < f_{17}(n) < f_{15}(n) < f_{13}(n) < f_7(n) < f_{18}(n) f 6 ( n ) <= f 10 ( n ) < f 4 ( n ) <= f 11 ( n ) < f 5 ( n ) < f 16 ( n ) <= f 1 ( n ) <= f 2 ( n ) < f 3 ( n ) <= f 12 ( n ) < f 8 ( n ) < f 9 ( n ) < f 14 ( n ) < f 17 ( n ) < f 15 ( n ) < f 13 ( n ) < f 7 ( n ) < f 18 ( n )
这是这些函数的渐近增长率的顺序。
常数函数 :显然,对于足够大的n,任何常数函数都比对数、线性、多项式、指数函数小:
𝑓 6 ( 𝑛 ) = 1 𝑓_6(𝑛) = 1 f 6 ( n ) = 1 𝑓 10 ( 𝑛 ) = 700 𝑓_{10}(𝑛) = 700 f 10 ( n ) = 700 对数函数 :当n增大时,对数函数的增长率低于线性函数,但高于常数函数。其中,𝑙 𝑜 𝑔 ( 𝑛 ) 𝑙𝑜𝑔(\sqrt{𝑛}) l o g ( n ) 实质上是1 2 𝑙 𝑜 𝑔 ( 𝑛 ) \frac{1}{2}𝑙𝑜𝑔(𝑛) 2 1 l o g ( n ) ,因此增长更慢:
𝑓 4 ( 𝑛 ) = 𝑙 𝑜 𝑔 ( 𝑛 ) = 1 2 l o g ( n ) 𝑓_4(𝑛) = 𝑙𝑜𝑔(\sqrt{𝑛}) = \frac{1}{2} log(n) f 4 ( n ) = l o g ( n ) = 2 1 l o g ( n ) 𝑓 11 ( 𝑛 ) = 𝑙 𝑜 𝑔 ( 𝑛 ) 𝑓_{11}(𝑛) = 𝑙𝑜𝑔(𝑛) f 11 ( n ) = l o g ( n ) 同时,𝑙 𝑜 𝑔 ( 𝑛 ) \sqrt{𝑙𝑜𝑔(𝑛)} l o g ( n ) 随着n的增长而增长,但速度慢于直接的log(n):
𝑓 5 ( 𝑛 ) = 𝑙 𝑜 𝑔 ( 𝑛 ) 𝑓_5(𝑛) = \sqrt{𝑙𝑜𝑔(𝑛)} f 5 ( n ) = l o g ( n ) 线性函数 :这些函数与n成正比。显然,𝑛 𝑛 n 和500 𝑛 500𝑛 500 n 的增长速度比n 3 \frac{n}{3} 3 n 要快:
𝑓 16 ( 𝑛 ) = n 3 𝑓_{16}(𝑛) = \frac{n}{3} f 16 ( n ) = 3 n 𝑓 1 ( 𝑛 ) = 𝑛 𝑓_1(𝑛) = 𝑛 f 1 ( n ) = n 𝑓 2 ( 𝑛 ) = 500 𝑛 𝑓_2(𝑛) = 500𝑛 f 2 ( n ) = 500 n 线性对数函数 :𝑛 ⋅ 𝑙 𝑜 𝑔 ( 𝑛 ) 𝑛 · 𝑙𝑜𝑔(𝑛) n ⋅ l o g ( n ) ,它的增长速度介于线性和多项式之间:
𝑓 8 ( 𝑛 ) = 𝑛 ⋅ 𝑙 𝑜 𝑔 ( 𝑛 ) 𝑓_8(𝑛) = 𝑛 · 𝑙𝑜𝑔(𝑛) f 8 ( n ) = n ⋅ l o g ( n ) 分数线性函数 :随着n的增长,分母l o g ( n ) log(n) l o g ( n ) 增加,使得整体函数的增长减慢,但它仍然比纯线性函数增长得快:
𝑓 9 ( 𝑛 ) = n l o g ( n ) 𝑓_9(𝑛) = \frac{n}{log(n)} f 9 ( n ) = l o g ( n ) n 平方根函数 :这类函数的增长比线性慢,但比对数快:
𝑓 3 ( 𝑛 ) = 𝑛 𝑓_3(𝑛) = \sqrt{𝑛} f 3 ( n ) = n 𝑓 12 ( 𝑛 ) = 9 n = 3 n 𝑓_{12}(𝑛) = \sqrt{9n} = 3\sqrt{n} f 12 ( n ) = 9 n = 3 n 平方函数 :明显比线性和平方根函数增长得快:
𝑓 14 ( 𝑛 ) = 𝑛 2 𝑓_{14}(𝑛) = 𝑛^2 f 14 ( n ) = n 2 立方根和立方函数 :
𝑓 17 ( 𝑛 ) = n 3 = n 2 3 𝑓_{17}(𝑛) = \sqrt{n^3} = n^\frac{2}{3} f 17 ( n ) = n 3 = n 3 2 ,它的增长比n 2 n^2 n 2 慢,但比n n n 快。𝑓 15 ( 𝑛 ) = n 3 𝑓_{15}(𝑛) = n^3 f 15 ( n ) = n 3 ,显然,它的增长速度是所有多项式函数中最快的。指数函数 :显然,3 𝑛 3^𝑛 3 n 的增长速度比2 𝑛 2^𝑛 2 n 快,它们都明显比多项式函数快:
𝑓 13 ( 𝑛 ) = 2 𝑛 𝑓_{13}(𝑛) = 2^𝑛 f 13 ( n ) = 2 n 𝑓 7 ( 𝑛 ) = 3 𝑛 𝑓_7(𝑛) = 3^𝑛 f 7 ( n ) = 3 n 阶乘函数 :增长最快。
𝑓 18 ( 𝑛 ) = 𝑛 ! 𝑓_{18}(𝑛) = 𝑛! f 18 ( n ) = n ! 整合上述分析,我们得到的排序为:𝑓 6 ( 𝑛 ) ≤ 𝑓 10 ( 𝑛 ) ≤ 𝑓 4 ( 𝑛 ) ≤ 𝑓 11 ( 𝑛 ) ≤ 𝑓 5 ( 𝑛 ) ≤ 𝑓 16 ( 𝑛 ) ≤ 𝑓 1 ( 𝑛 ) ≤ 𝑓 2 ( 𝑛 ) ≤ 𝑓 3 ( 𝑛 ) ≤ 𝑓 12 ( 𝑛 ) ≤ 𝑓 9 ( 𝑛 ) ≤ 𝑓 8 ( 𝑛 ) ≤ 𝑓 14 ( 𝑛 ) ≤ 𝑓 17 ( 𝑛 ) ≤ 𝑓 15 ( 𝑛 ) ≤ 𝑓 13 ( 𝑛 ) ≤ 𝑓 7 ( 𝑛 ) ≤ 𝑓 18 ( 𝑛 ) 𝑓_6(𝑛) \leq 𝑓_{10}(𝑛) \leq 𝑓_4(𝑛) \leq 𝑓_{11}(𝑛) \leq 𝑓_5(𝑛) \leq 𝑓_{16}(𝑛) \leq 𝑓_1(𝑛) \leq 𝑓_2(𝑛) \leq 𝑓_3(𝑛) \leq 𝑓_{12}(𝑛) \leq 𝑓_9(𝑛) \leq 𝑓_8(𝑛) \leq 𝑓_{14}(𝑛) \leq 𝑓_{17}(𝑛) \leq 𝑓_{15}(𝑛) \leq 𝑓_{13}(𝑛) \leq 𝑓_7(𝑛) \leq 𝑓_{18}(𝑛) f 6 ( n ) ≤ f 10 ( n ) ≤ f 4 ( n ) ≤ f 11 ( n ) ≤ f 5 ( n ) ≤ f 16 ( n ) ≤ f 1 ( n ) ≤ f 2 ( n ) ≤ f 3 ( n ) ≤ f 12 ( n ) ≤ f 9 ( n ) ≤ f 8 ( n ) ≤ f 14 ( n ) ≤ f 17 ( n ) ≤ f 15 ( n ) ≤ f 13 ( n ) ≤ f 7 ( n ) ≤ f 18 ( n )
Given the generator function, write the output: (10 minutes) 1. 大O和大Θ 的区别是什么?
1. 大O和大Θ 的区别是什么?
大O符号((O))和大Θ符号((\Theta))都是计算机科学中用于描述算法复杂性的渐近记号,但它们描述的角度和含义略有不同:
大O符号(O) : 描述算法的上界。当我们说一个算法的时间复杂度是 (O(f(n))) 时,我们意味着在最坏的情况下,该算法的执行时间会按 (f(n)) 的速率增长(或更慢)。简言之,(O(f(n))) 提供了算法性能的一个上限。
例如,如果一个算法的时间复杂度为 (O(n^2)),那么我们可以认为在最坏的情况下,该算法的执行时间不会比 (n^2) 快速增长。
大Θ符号(Θ) : 描述算法的上界和下界,并且这两个界限是相同的。当我们说一个算法的时间复杂度是 (\Theta(f(n))) 时,我们意味着在最坏的情况下,该算法的执行时间按 (f(n)) 的速率增长,而在最好的情况下,它也是 (f(n))。也就是说,(\Theta(f(n))) 描述了算法性能的确切增长率。
例如,如果一个算法的时间复杂度为 (\Theta(n^2)),这意味着无论是最好的情况还是最坏的情况,该算法的执行时间都会按 (n^2) 的速率增长。
简言之,大O给出了性能的上界(可能达到的最差性能),而大Θ给出了确切的性能描述,在最好和最坏情况下都符合该描述。
当然可以,我会通过几个简单的算法例子来解释这两个渐近符号。
算法 :给定一个数组和一个目标值,线性查找算法会遍历整个数组,寻找是否存在目标值。
分析 :
最坏情况:目标值在数组的最后一个位置或根本不存在。此时,你需要检查整个数组,所以时间复杂度是 (O(n))。 最好情况:目标值就在数组的第一个位置。时间复杂度是 (O(1))。 平均情况:时间复杂度是 (O(n))。 因为最好和最坏的情况之间的时间复杂度不相同,我们不能为此算法提供一个 (\Theta) 表述。
算法 :在一个有序数组中寻找目标值。每次迭代都将数组分成两半,直到找到目标值或者搜索区间为空。
分析 :
最坏情况:需要检查整个数组,直到只剩一个元素。时间复杂度是 (O(\log n))。 最好情况:目标值恰好在数组中间。时间复杂度是 (O(1))。 平均情况:时间复杂度是 (O(\log n))。 同样,由于最好和最坏情况之间的时间复杂度不相同,我们不能为此算法提供一个 (\Theta) 表述。
算法 :通过多次遍历数组,每次都将相邻的元素进行比较并交换,直到整个数组排序完成。
分析 :
最坏情况:当数组是完全逆序的时候,时间复杂度是 (O(n^2))。 最好情况:当数组已经是排序好的,只需遍历一次数组以确认,时间复杂度是 (O(n))。 平均情况:时间复杂度是 (O(n^2))。 尽管最好的情况时间复杂度是 (O(n)),但通常冒泡排序被认为是一个 (O(n^2)) 的排序算法,因为在许多情况下都表现为 (O(n^2))。
希望这几个例子有助于你更好地理解渐近时间复杂度以及大O和大Θ的区别。当然,实际应用中,很多时候我们更关注最坏情况或平均情况的时间复杂度,因为这有助于我们评估算法在各种场景下的性能表现。
公众号:AI悦创【二维码】 AI悦创·编程一对一
AI悦创·推出辅导班啦,包括「Python 语言辅导班、C++ 辅导班、java 辅导班、算法/数据结构辅导班、少儿编程、pygame 游戏开发、Web、Linux」,全部都是一对一教学:一对一辅导 + 一对一答疑 + 布置作业 + 项目实践等。当然,还有线下线上摄影课程、Photoshop、Premiere 一对一教学、QQ、微信在线,随时响应!微信:Jiabcdefh
C++ 信息奥赛题解,长期更新!长期招收一对一中小学信息奥赛集训,莆田、厦门地区有机会线下上门,其他地区线上。微信:Jiabcdefh
方法一:QQ
方法二:微信:Jiabcdefh