算法復雜度的表示法_用簡單的英語算法:時間復雜度和Big-O表示法

算法復雜度的表示法

by Michael Olorunnisola

通過Michael Olorunnisola

用簡單的英語算法:時間復雜度和Big-O表示法 (Algorithms in plain English: time complexity and Big-O notation)

Every good developer has time on their mind. They want to give their users more of it, so they can do all those things they enjoy. They do this by minimizing time complexity.

每個優秀的開發人員都有自己的時間。 他們想給用戶更多的東西,以便他們可以做自己喜歡的所有事情。 他們通過最小化時間復雜度來做到這一點。

Before you can understand time complexity in programming, you have to understand where it’s most commonly applied: in the design of algorithms.

在您了解編程中的時間復雜性之前,您必須了解它最常應用的地方:在算法設計中。

那么,什么是算法? (So what’s an algorithm, anyway?)

Simply put, an algorithm is a series of contained steps, which you follow in order to achieve some goal, or to produce some output. Let’s take for example your grandma’s recipe for baking a cake. Wait, does that count as an algorithm? Sure it does!

簡而言之,算法是一系列包含的步驟,為了實現某些目標或產生某些輸出,必須遵循這些步驟。 讓我們以您奶奶的烤蛋糕食譜為例。 等等,算作算法嗎? 當然可以!

function BakeCake(flavor, icing){
"1. Heat Oven to 350 F2. Mix flour, baking powder, salt3. Beat butter and sugar until fluffy4. Add eggs.5. Mix in flour, baking powder, salt6. Add milk and " + flavor + "7. Mix further8. Put in pan9. Bake for 30 minutes
10." + if(icing === true) return 'add icing' + "
10. Stuff your face
"
}BakeCake('vanilla', true) => deliciousness

Algorithms are useful in our examination of time complexity because they come in all shapes and sizes.

由于算法具有各種形狀和大小,因此在我們檢查時間復雜度方面很有用。

In the same way you can slice a pie a 100 different ways, you can solve a single problem with many different algorithms. Some solutions are just more efficient, taking less time and requiring less space than others.

以相同的方式,您可以用100種不同的方式對一個餅進行切片,可以使用許多種不同的算法來解決一個問題。 與其他解決方案相比,某些解決方案效率更高,所需時間更少,占用的空間更少。

So the main question is: how do we go about analyzing which solutions are most efficient?

因此,主要問題是:我們如何分析哪些解決方案最有效?

Math to the rescue! Time complexity analysis in programming is just an extremely simplified mathematical way of analyzing how long an algorithm with a given number of inputs (n) will take to complete it’s task. It’s usually defined using Big-O notation.

求救數學! 編程中的時間復雜度分析只是一種極其簡化的數學方法,用于分析具有給定數量輸入(n)的算法完成任務所需的時間。 通常使用Big-O表示法定義。

您問什么是大O符號? (What’s Big O notation, you ask?)

If you promise you won’t give up and stop reading, I will tell you.

如果您保證不會放棄并停止閱讀,我會告訴您。

Big-O notation is a way of converting the overall steps of an algorithm into algebraic terms, then excluding lower order constants and coefficients that don’t have that big an impact on the overall complexity of the problem.

Big-O表示法是一種將算法的整體步驟轉換為代數項,然后排除對問題的整體復雜性影響不大的低階常量和系數的方法。

Mathematicians will probably cringe a bit at my “overall impact” assumption there, but for developers to save time, it’s easier to simplify things this way:

數學家可能會對我的“總體影響”假設有些畏縮,但是對于開發人員來說,為了節省時間,用這種方式簡化事情會更容易:

Regular       Big-O2             O(1)   --> It's just a constant number2n + 10       O(n)   --> n has the largest effect5n^2          O(n^2) --> n^2 has the largest effect

In short, all this example is saying is: we only look at the factor in our expression that has the potential greatest impact on the value that our expression will return. (This changes as the constant gets extremely large and n gets small, but let’s not worry about that for now).

簡而言之,此示例說明的是:我們僅查看表達式中對表達式返回的值具有最大潛在影響的因素。 (隨著常數變得非常大而n變得很小,這種情況會發生變化,但是現在我們不必擔心這一點)。

Below are some common time complexities with simple definitions. Feel free to check out Wikipedia, though, for more in-depth definitions.

以下是一些具有簡單定義的常見時間復雜性。 請隨意查看Wikipedia ,以獲得更深入的定義。

  • O(1) — Constant Time: Given an input of size n, it only takes a single step for the algorithm to accomplish the task.

    O(1)-恒定時間:給定大小為n的輸入,算法只需一步即可完成任務。
  • O(log n) — Logarithmic time: given an input of size n, the number of steps it takes to accomplish the task are decreased by some factor with each step.

    O(log n)-對數時間:給定大小為n的輸入,完成任務所需的步驟數會因每個步驟而減少一些。
  • O(n) — Linear Time: Given an input of size n, the number of of steps required is directly related (1 to 1)

    O(n)—線性時間:給定大小為n的輸入,所需的步數直接相關(1到1)
  • O(n2) — Quadratic Time: Given an input of size n, the number of steps it takes to accomplish a task is square of n.

    O(n2)—二次時間:給定大小為n的輸入,完成一項任務所需的步驟數為n的平方。
  • O(C^n) — Exponential Time: Given an input of size n, the number of steps it takes to accomplish a task is a constant to the n power (pretty large number).

    O(C ^ n)—指數時間:在輸入大小為n的情況下,完成一項任務所需的步驟數是n次冪的常數(相當大的數字)。

With this knowledge in hand, lets see the number of steps that each of these time complexities entails:

掌握了這些知識之后,讓我們看一下這些時間復雜度所需要的步驟數:

let n = 16;O (1) = 1 step "(awesome!)"O (log n) = 4 steps  "(awesome!)" -- assumed base 2O (n) = 16 steps "(pretty good!)"O(n^2) = 256 steps "(uhh..we can work with this?)"O(2^n) = 65,536 steps "(...)"

As you can see, things can easily become orders of magnitude more complex depending on the complexity of your algorithm. Luckily, computers are powerful enough to still handle really large complexities relatively quickly.

如您所見,根據算法的復雜性,事情很容易變得復雜幾個數量級。 幸運的是,計算機功能強大,仍然可以相對快速地處理非常大的復雜性。

So how do we go about analyzing our code with Big-O notation?

那么,我們如何使用Big-O表示法分析代碼?

Well here are some quick and simple examples of how you can apply this knowledge to algorithms you might encounter in the wild or code up yourself.

好了,這里有一些快速簡單的示例,說明如何將這些知識應用于野外可能遇到的算法或自己編寫代碼。

We’ll use the data structures below for our examples:

我們將使用以下數據結構作為示例:

var friends = {'Mark' : true,'Amy' : true,'Carl' : false,'Ray' :  true,
'Laura' : false,
}
var sortedAges = [22, 24, 27, 29, 31]

O(1)-恒定時間 (O(1) — Constant Time)

Value look ups when you know the key (objects) or the index (arrays) always take one step, and are thus constant time.

當您知道鍵(對象)或索引(數組)總是邁出一步,并且時間恒定時,就會進行值查找。

//If I know the persons name, I only have to take one step to check:function isFriend(name){ //similar to knowing the index in an Array return friends[name]; 
};isFriend('Mark') // returns True and only took one stepfunction add(num1,num2){ // I have two numbers, takes one step to return the valuereturn num1 + num2
}

O(log n)-對數時間 (O(log n) — Logarithmic Time)

If you know which side of the array to look on for an item, you save time by cutting out the other half.

如果您知道要在陣列的哪一側查找某項,則可以省去另一半來節省時間。

//You decrease the amount of work you have to do with each stepfunction thisOld(num, array){var midPoint = Math.floor( array.length /2 );if( array[midPoint] === num) return true;if( array[midPoint] < num ) --> only look at second half of the arrayif( array[midpoint] > num ) --> only look at first half of the array//recursively repeat until you arrive at your solution}thisOld(29, sortedAges) // returns true //Notes//There are a bunch of other checks that should go into this example for it to be truly functional, but not necessary for this explanation.//This solution works because our Array is sorted//Recursive solutions are often logarithmic//We'll get into recursion in another post!

O(n)—線性時間 (O(n) — Linear Time)

You have to look at every item in the array or list to accomplish the task. Single for loops are almost always linear time. Also array methods like indexOf are also linear time. You’re just abstracted away from the looping process.

您必須查看數組或列表中的每個項目才能完成任務。 單次for循環幾乎總是線性時間。 像indexOf這樣的數組方法也是線性時間。 您只是從循環過程中抽象出來。

//The number of steps you take is directly correlated to the your input sizefunction addAges(array){var sum = 0;for (let i=0 ; i < array.length; i++){  //has to go through each valuesum += array[i]}return sum;
}addAges(sortedAges) //133

O(n2)—二次時間 (O(n2) — Quadratic Time)

Nested for loops are quadratic time, because you’re running a linear operation within another linear operation (or n*n = n2).

嵌套的for循環是二次時間,因為您正在另一個線性運算(或n * n =n2)內運行線性運算。

//The number of steps you take is your input size squaredfunction addedAges(array){var addedAge = [];for (let i=0 ; i < array.length; i++){ //has to go through each valuefor(let j=i+1 ; j < array.length ; j++){ //and go through them againaddedAge.push(array[i] + array[j]);}}return addedAge;
}addedAges(sortedAges); //[ 46, 49, 51, 53, 51, 53, 55, 56, 58, 60 ]//Notes//Nested for loops. If one for loop is linear time (n)//Then two nested for loops are (n * n) or (n^2) Quadratic!

O(2 ^ n)—指數時間 (O(2^n) — Exponential Time)

Exponential time is usually for situations where you don’t know that much, and you have to try every possible combination or permutation.

指數時間通常用于您不太了解的情況,并且您必須嘗試所有可能的組合或排列。

//The number of steps it takes to accomplish a task is a constant to the n power//Thought example//Trying to find every combination of letters for a password of length n

You should do time complexity analysis anytime you write code that has to run fast.

每當您編寫必須快速運行的代碼時,都應該進行時間復雜度分析。

When you have various routes to solve a problem, it is definitely wiser to create a solution that just works first. But in the long run, you’ll want a solution that runs as quickly and efficiently as possible.

當您有各種解決問題的途徑時,明智的做法是首先創建一個解決方案。 但是從長遠來看,您將需要一個盡可能快速高效地運行的解決方案。

To help you with the problem solving process, here are some simple questions to ask:

為了幫助您解決問題,以下是一些簡單的問題:

1. Does this solve the problem? Yes =>

1.這樣可以解決問題嗎? =>

1. Does this solve the problem? Yes =>

1.這樣可以解決問題嗎? =>

2. Do you have time to work on this

2.您有時間從事此工作嗎

2. Do you have time to work on this

2.您有時間從事此工作嗎

2. Do you have time to work on thisYes => go to step 3

2.您是否有時間進行此工作, =>轉到步驟3

2. Do you have time to work on thisYes => go to step 3

2.您是否有時間進行此工作, =>轉到步驟3

2. Do you have time to work on thisYes => go to step 3No => Come back to it later and go to step 6 for now.

2.您是否有時間進行此工作 =>轉到步驟3 =>稍后再回到步驟6,現在轉到步驟6。

2. Do you have time to work on thisYes => go to step 3No => Come back to it later and go to step 6 for now.

2.您是否有時間進行此工作 =>轉到步驟3 =>稍后再回到步驟6,現在轉到步驟6。

3. Does it cover all edge cases? Yes =>

3.它涵蓋所有邊緣情況嗎? =>

3. Does it cover all edge cases? Yes =>

3.它涵蓋所有邊緣情況嗎? =>

4. Are my complexities as low as possible ?

4.我的復雜程度是否盡可能低?

4. Are my complexities as low as possible ?

4.我的復雜程度是否盡可能低?

4. Are my complexities as low as possible ?No => rewrite or modify into a new solution –>go back to step 1

4.我的復雜程度是否盡可能低? =>重寫或修改為新解決方案–>返回步驟1

4. Are my complexities as low as possible ?No => rewrite or modify into a new solution –>go back to step 1

4.我的復雜程度是否盡可能低? =>重寫或修改為新解決方案–>返回步驟1

4. Are my complexities as low as possible ?No => rewrite or modify into a new solution –>go back to step 1Yes => go to step 5

4.我的復雜程度是否盡可能低? =>重寫或修改為新解決方案–>返回步驟1 =>轉到步驟5

4. Are my complexities as low as possible ?No => rewrite or modify into a new solution –>go back to step 1Yes => go to step 5

4.我的復雜程度是否盡可能低? =>重寫或修改為新解決方案–>返回步驟1 =>轉到步驟5

5. Is my code D.R.Y ? Yes =>

5.我的代碼是DRY嗎? =>

5. Is my code D.R.Y ? Yes =>

5.我的代碼是DRY嗎? =>

6. Rejoice!

6.歡喜!

6. Rejoice!

6.歡喜!

6. Rejoice!No => Make it D.R.Y, then rejoice!

6.歡喜! =>使其干燥,然后高興!

Analyze time complexity any and all times you are trying to solve a problem. It’ll make you a better developer in the log run. Your teammates and users will love you for it.

您嘗試解決問題的所有時間都要分析時間復雜度。 它可以使您成為日志運行中更好的開發人員。 您的隊友和用戶將為此而愛您。

Again, most problems you will face as programmer — whether algorithmic or programmatic — will have tens if not hundreds of ways of solving it. They may vary in how they solve the problem, but they all still solve that problem.

同樣,您將以編程人員的身份遇到的大多數問題,無論是算法上還是程序上的問題,都有數十種甚至數百種解決方法。 他們解決問題的方式可能有所不同,但是他們仍然都能解決問題。

You could be making decisions between whether to use sets or graphs to store data. You could be deciding whether or not to use Angular, React, or Backbone for a team project. All of these solutions solve the same problem in a different way.

您可能在決定使用集還是使用圖來存儲數據之間做出決定。 您可能正在決定是否為團隊項目使用Angular,React或Backbone。 所有這些解決方案都以不同的方式解決了相同的問題。

Given this, it’s hard to say there is a single “right” or “best” answer to these problems. But it is possible to say there are “better” or “worse” answers to a given problem.

鑒于此,很難說對這些問題有一個“正確”或“最佳”答案。 但是可以說,對于給定的問題有“更好”或“更差”的答案。

Using one of our previous examples, it might be better to use React for a team project if half your team has experience with it, so it’ll take less time to get up and running.

使用我們之前的示例之一,如果您的團隊有一半的經驗,將React用于團隊項目可能會更好,因此啟動和運行將花費更少的時間。

The ability to describe a better solution usually springs from some semblance of time complexity analysis.

描述更好的解決方案的能力通常源于某種時間復雜度分析。

In short, if you’re going to solve a problem, solve it well. And use some Big-O to help you figure out how.

簡而言之,如果您要解決問題,請很好地解決。 并使用一些Big-O來幫助您找出方法。

Here’s a final recap:

這是最后的總結:

  • O(1) — Constant Time: it only takes a single step for the algorithm to accomplish the task.

    O(1)—恒定時間:算法僅需一步即可完成任務。

  • O(log n) — Logarithmic Time: The number of steps it takes to accomplish a task are decreased by some factor with each step.

    O(log n)-對數時間:完成一項任務所需要執行的步驟數,每一步都會減少一些。

  • O(n) — Linear Time: The number of of steps required are directly related (1 to 1).

    O(n)—線性時間:所需步驟數直接相關(1到1)。

  • O(n2) — Quadratic Time: The number of steps it takes to accomplish a task is square of n.

    O(n2)—二次時間:完成一項任務所需的步驟數為n的平方。

  • O(C^n) — Exponential: The number of steps it takes to accomplish a task is a constant to the n power (pretty large number).

    O(C ^ n)—指數:完成一項任務所需的步驟數是n次冪的常數(非常大的數字)。

And here are some helpful resources to learn more:

以下是一些有用的資源,以了解更多信息:

  • Wikipedia

    維基百科

  • The Big O Cheat Sheet is a great resource with common algorithmic time complexities and a graphical representation. Check it out!

    Big O備忘單是一個很好的資源,具有常見的算法時間復雜度和圖形表示形式。 看看這個!

翻譯自: https://www.freecodecamp.org/news/time-is-complex-but-priceless-f0abd015063c/

算法復雜度的表示法

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/396311.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/396311.shtml
英文地址,請注明出處:http://en.pswp.cn/news/396311.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android Studio 開始運行錯誤

/********************************************************************************* Android Studio 開始運行錯誤* 說明&#xff1a;* 打開Android Studio就拋出這個錯誤。* * 2017-4-1 深圳 南…

IOS 計步器

這篇博客介紹的是當前比較流行的“計步器”-只是簡單的知識點 計步器的實現在IOS8開始進行了改變。 但是我會對之前之后的都進行簡單介紹。 IOS 8 - // // ViewController.m // CX 計步器 // // Created by ma c on 16/4/12. // Copyright © 2016年 bjsxt. All rights…

vue學習之二ECMAScript6標準

一、ECMAScript6標準簡述 ECMAScript 6.0&#xff08;以下簡稱 ES6&#xff09;是 JavaScript 語言的下一代標準&#xff0c;已經在 2015 年 6 月正式發布了。它的目標&#xff0c;是使得 JavaScript 語言可以用來編寫復雜的大型應用程序&#xff0c;成為企業級開發語言。 1.1E…

抖音吸粉_抖音吸粉5大實用方法首次分享!輕松實現粉絲10000+

抖音&#xff0c;是一款可以拍短視頻的音樂創意短視頻社交軟件&#xff0c;該軟件于2016年9月上線&#xff0c;是一個專注年輕人音樂短視頻社區。用戶可以通過這款軟件選擇歌曲&#xff0c;拍攝音樂短視頻&#xff0c;形成自己的作品。抖音APP僅推出半年&#xff0c;用戶量就突…

mapper mysql 主鍵_實現通用mapper主鍵策略兼容mysql和oracle

【原創文章&#xff0c;轉載請注明原文章地址&#xff0c;謝謝&#xff01;】1.直接用官方提供的注解方法是無法達到兼容效果的2.跟蹤源碼看看是否有其他方法3.這里有個genSql&#xff0c;可以看一下這個類4.創建一個自定義的處理類實現GenSql(代碼中是我實際項目中用到的策略&…

權限分配界面 純手工 僅用到bootstrap的架構 以及 c標簽

<div class"form-group"> <div class"row"> <label class"col-sm-2 control-label">配置權限</label> <div class"col-sm-10"> <c:forEach var"m" items…

數據管理與數據庫 大學課程_根據數據顯示的50種最佳免費在線大學課程

數據管理與數據庫 大學課程When I launched Class Central back in November 2011, there were around 18 or so free online courses, and almost all of them were from Stanford.當我在2011年11月推出Class Central時&#xff0c;大約有18項免費在線課程&#xff0c;幾乎所有…

每天一個linux命令(12):more命令

more命令&#xff0c;功能類似 cat &#xff0c;cat命令是整個文件的內容從上到下顯示在屏幕上。 more會以一頁一頁的顯示方便使用者逐頁閱讀&#xff0c;而最基本的指令就是按空白鍵&#xff08;space&#xff09;就往下一頁顯示&#xff0c;按 b 鍵就會往回&#xff08;back&…

java 面試題 由淺入深_面試官由淺入深的面試套路

閱讀文本大概需要3分鐘。從上圖看來面試官面試是有套路的&#xff0c;一不小心就一直被套路。0x01&#xff1a;Thread面試官&#xff1a;創建線程有哪幾種方式&#xff1f;應聘者&#xff1a;繼承Thread類、實現Runable接口、使用j.u.c中的線程池面試官&#xff1a;繼承Thread類…

怎么用centos7運行c語言程序_centos如何編譯c語言代碼

centos如何編譯c語言代碼,文件,選項,作用,鏈接,程序 centos如何編譯c語言代碼 易采站長站,站長之家為您整理了centos如何編譯c語言代碼的相關內容。 編譯c,c++代碼 安裝gcc 1、使用如下命令查詢 centos 官方gcc的所有包:yum -list gcc* 可安裝的軟件包gcc.x86_64gcc-c++.x86…

第四篇:基本數據類型及用法(1)

字符串&#xff08;str型&#xff09; -可以做加法&#xff0c;乘法 乘法例&#xff1a; n1"alex" n2n1*3 print(n2) #結果&#xff1a;alexalexalex -首字母大寫: capitalize() -所有字母變小寫: casefold()、lower() #casefold更牛&#xff0c;很多未知的對應關系也…

Android Studio 錯誤集

錯誤列表與解決方案: 1.Android studio Gradle project sync failed Android studio 構建項目出錯 Error:Unable to start the daemon process: could not reserve enough space for object heap.Please assign more memory to Gradle in the projects gradle.properties file.…

需求簡報_代碼簡報:我如何通過做自己喜歡的事情來獲得頂級技術實習

需求簡報Here are three stories we published this week that are worth your time:這是我們本周發布的三個值得您關注的故事&#xff1a; How I landed a top-tier tech internship by doing something I love: 7 minute read 我如何通過做自己喜歡的事情獲得一流的技術實習…

review what i studied `date` - 2017-3-31

在11 月份內&#xff0c;每天的早上6 點到12 點中&#xff0c;每隔2 小時執行一次/usr/bin/httpd.sh 怎么實現0 6-12/2 * 11 * /usr/bin/httpd.shNginx中的ip_hash是指講一個地址的請求永久分發至后端的一臺RealServer&#xff0c;直至這臺RealServer宕機Zabbix和Nagios的工作原…

java string轉long報錯_java.lang.Integer cannot be cast to java.lang.Long解決辦法

你好我是辰兮&#xff0c;本次是項目遇到的java.lang.Integer cannot be cast to java.lang.Long異常以及相對應的解決方案。文章目錄一、實戰問題用postman測試數據報錯&#xff0c;類型轉換異常&#xff01;如何將Integer類型轉換成長整形 &#xff1f;先轉成String型&#x…

pyqt 界面關閉信號_木辛老師的編程課堂之Python和Qt實戰慕課軟件開發:增加關閉按鈕...

軟件實戰開始&#xff0c;快速提供編程能力&#xff1b;通過實戰&#xff0c;分析產品需求&#xff0c;梳理設計需求&#xff0c;提升項目分析和架構的能力。快點跟著木辛老師一起學習吧&#xff01;請點擊右上角“關注”按鈕關注我們喲&#xff1a;跟著木辛老師學習Python編程…

從零開始nodejs系列文章

http://blog.fens.me/series-nodejs/轉載于:https://www.cnblogs.com/chinafbi/p/5394482.html

Leetcode589.N-ary Tree Preorder TraversalN叉樹的前序遍歷

給定一個 N 叉樹&#xff0c;返回其節點值的前序遍歷。 class Node { public:int val;vector<Node*> children;Node() {}Node(int _val, vector<Node*> _children) {val _val;children _children;} };//遞歸 class Solution { public:vector<int> res;vect…

打破雙親委派么,怎么打破_質量保證被打破。 這就是我們如何使其像其他所有東西一樣敏捷。...

打破雙親委派么,怎么打破by Derwin由Derwin 質量保證被打破。 這就是我們如何使其像其他所有東西一樣敏捷。 (Quality Assurance is broken. Here’s how we can make it as agile as everything else.) Process is the key to great software.過程是出色軟件的關鍵。 In gen…

android java.lang.linkageerror_使用eclipse中的maven構建web應用出現 java.lang.LinkageError異常...

????: Servlet.service() for servlet [jsp] in context with path [/webdemo] threw exception [java.lang.LinkageError: loader constraint violation: loader (instance of org/apache/jasper/servlet/JasperLoader) previously initiated loading for a different typ…