大o符号_在5分钟内学习大O符号

大o符号

Big O Notation is often ignored by developers. However, It is a fundamental notion, very helpful and very easy to understand.

大O表示法经常被开发人员忽略。 但是,这是一个基本概念, 非常有用并且非常容易理解

Let's learn in few minutes what is it.

让我们在几分钟内了解它是什么。

大O符号 (The Big O Notation)

Big O Notation (or algorithmic complexity) is a standard way to measure the performance of an algorithm. It uses a mathematical way to judge the effectiveness of your code.

大O表示法(或算法复杂度)是一种衡量算法性能的标准方法。 它使用数学方法来判断代码的有效性

Don't be too afraid by the word "mathematical". It is only basic operations you already know.

不要太害怕“数学”一词。 这只是您已经知道的基本操作。

This notation allows you to measure the evolution of the growth rate of your algorithm compared to the input data. It will describe the worst possible case in terms of performance of your code.

该符号使您可以测量算法与输入数据相比的增长率。 它将描述代码性能方面最糟糕的情况

The power of this notation is to be able to measure the efficiency of an algorithm without being affected by an external event such as bad connection, hardware stuff, etc. It is based on a single criterion: the number of operations to be performed.

这种表示法的功能是能够测量算法的效率,而不受诸如连接不良,硬件不足等外部事件的影响。 它基于一个标准:要执行的操作数。

一个基本的例子 (A Basic Example)

Let’s discover a basic example to really understand what is this notation.

让我们发现一个基本的例子来真正理解这个表示法。

Imagine you are in an interview for a job. One of the technical test is to create a function which takes as input a number n and which returns the sum of the numbers from 0 to n.

想象您正在面试工作。 一种技术测试是创建一个将数字n作为输入并返回从0到n的数字之和的函数。

A naive implementation would be to iterate from 0 to n, and perform an addition at each iteration.

天真的实现是从0迭代到n,并在每次迭代时执行加法。

Image for post
Basic example using JavaScript
使用JavaScript的基本示例

If I received 10 as input, I will have 10 iterations. If I got 1 million as input, I will have 1 million iterations. The number of iteration is equal to the input given.

如果我收到10个输入,则将有10次迭代。 如果我得到一百万次输入,那么我将进行一百万次迭代。 迭代次数等于给定的输入。

We have a linear execution time. We can say that this algorithm has a complexity of O(n). The number n in parentheses means the number of iteration to performed is equal to the input.

我们有一个线性的执行时间。 可以说该算法的复杂度为O(n)。 括号中的数字n表示要执行的迭代次数等于输入。

The best solution for this exercise is to use the famous method n * (n + 1) / 2.

此练习的最佳解决方案是使用著名的方法n *(n + 1)/ 2。

Image for post
Basic example optimized
基本示例已优化

Using this solution, whatever is the number given, there will be only one operation. The algorithm requires a constant time to execute, we say we have a complexity of O(1).

使用此解决方案,无论给出多少,都将只有一个操作。 该算法需要恒定的时间来执行,我们说我们的复杂度为O(1)。

In this case, O(1) doesn't necessarily means the algorithm is very fast. It can take few nanoseconds (like with our sumFrom0ToN function) or three minutes, depending on what the function does. What it means is the algorithm requires a constant time to execute no matter the amount of data given in input.

在这种情况下,O(1)不一定意味着算法非常快。 这可能需要几纳秒的时间(例如我们的 sumFrom0ToN 函数)或三分钟,具体取决于函数的功能。 这意味着无论输入中给出多少数据,该算法都需要恒定的时间来执行。

常见错误的例子 (Example of a common mistake)

You are starting to understand how Big O Notation works. Now let's see a very common case in the developer world.

您开始了解Big O符号的工作原理。 现在,让我们来看一个在开发人员世界中非常普遍的情况。

For the next exercise, you have two arrays, each containing n numbers. You have to write a function which returns true if a number is common to both arrays.

在下一个练习中,您有两个数组,每个数组包含n个数字。 您必须编写一个函数,如果两个数组共有一个数字,则该函数返回true。

The simple (and naive) way is to iterate on both arrays and return when there is a match.

一种简单(天真)的方法是在两个数组上进行迭代,并在匹配时返回。

Image for post

Let's say that the two arrays have a size of 10. In the worst case (no common number), we will have 10 * 10 iterations, 100 iterations in total. This algorithm has a complexity of O(n²).

假设两个数组的大小为10。在最坏的情况下(没有通用数),我们将有10 * 10的迭代,总共100迭代。 该算法的复杂度为O(n²)。

The best solution for this exercise is to use a map for one array to avoid having 2 nested loops.

此练习的最佳解决方案是将一个映射用于一个数组,以避免出现2个嵌套循环。

Image for post
The same example optimized
对同一示例进行了优化

In this optimized solution, we still have 2 loops but they are not nested anymore. In the worst case (no common number), we will have 10, plus 10 iterations, so 20 iterations in total. This algorithm has a complexity of O(2n) which is a lot better.

在此优化的解决方案中,我们仍然有2个循环,但它们不再嵌套。 在最坏的情况下(没有通用数),我们将有10次加上10次迭代,因此总共有20次迭代。 该算法的复杂度为O(2n),更好。

复杂的例子 (Complex Example)

Let's try a more complex example for this last one.

让我们为最后一个尝试一个更复杂的示例。

For the next exercise, you have to write an optimized algorithm which finds the position of a number in an array of numbers ordered from lowest to highest.

在下一个练习中,您必须编写一种优化算法,该算法可以找到从最低到最高顺序排列的数字数组中数字的位置。

The simple (and again naive) way to do it is to iterate from the beginning to the end of the array to find the position.

一种简单(也是天真的)方法是从数组的开头到结尾进行迭代以找到位置。

Image for post
The algorithm return -1 if the number is not find, but this is not important
如果找不到数字,该算法将返回-1,但这并不重要

You can see the similarity between this algorithm and the first one. A loop which iterates over all the elements of our array given as parameters. You guessed it, the complexity of this algorithm is O(n).

您可以看到该算法与第一个算法的相似性。 循环遍历作为参数给出的数组所有元素的循环。 您猜对了,该算法的复杂度为O(n)。

But the fact that the array contains ordered numbers allow us to use a much better algorithm: The binary search algorithm.

但是数组包含有序数字这一事实使我们可以使用更好的算法:二进制搜索算法。

Basically, rather than trying each number of the array, we will first try with the middle number. If this number is smaller than our number, we will repeat the same operation with the array that goes from this number to the end. On the other hand, if the element was greater than our number, we would repeat the operation with the array that goes from the start to this element.

基本上,我们首先尝试使用中间数字,而不是尝试数组的每个数字。 如果此数字小于我们的数字,我们将对从该数字到末尾的数组重复相同的操作。 另一方面,如果该元素大于我们的数字,我们将对从开始到该元素的数组重复该操作。

Image for post
Wikipedia 维基百科

The binary search algorithm runs in logarithmic time, its complexity is O(log(n)). This means, the execution time of the algorithm is still depending on the input (here, the size of our array). But the number of iteration doesn’t increase much when the number of input gets bigger.

二进制搜索算法以对数时间运行,其复杂度为O(log(n))。 这意味着,算法的执行时间仍取决于输入(此处为数组的大小)。 但是,当输入数量增加时,迭代次数不会增加太多。

Image for post
An implementation of the binary search algorithm in JavaScript using recursive functions.
使用递归函数JavaScript中二进制搜索算法的实现。

不同复杂度时间概述 (Overview of different complexity time)

There are different types of complexity time which are interesting to know.

有多种有趣的时间类型。

Image for post

Algorithms with constant or logarithm execution time are always the best when you need to treat an important amount of data.

当您需要处理大量数据时,执行时间恒定或对数的算法始终是最佳的。

Algorithms with linear execution time are fine too, but may suffer from some performance issues with large volumes of data.

具有线性执行时间的算法也很好,但是可能会因海量数据而遭受一些性能问题。

And finally, algorithms with an exponential execution time are to be avoided at all costs because they are too greedy and you will be faced with a problem sooner or later.

最后,应不惜一切代价避免执行时间成指数的算法,因为它们过于贪婪,迟早会遇到问题。

Big O Notation is important to know, it represents the efficiency of an algorithm and allows you to find more optimized means to achieve the same result.

大O表示法很重要,它表示算法的效率,使您可以找到更多优化的方法来达到相同的结果。

Even in times when performance does not matter, or the volume of data is very small, you still have to challenge yourself about the efficiency of your algorithm. And often, the most optimized way is also the most elegant to write it!

即使在性能无关紧要或数据量很小的时候,您仍然必须挑战算法的效率。 通常,最优化的方式也是最优雅的编写方式!

翻译自: https://medium.com/javascript-in-plain-english/learn-big-o-notation-in-5-minutes-c24e647c4309

大o符号

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值