什么是算法?
1. 什么是算法
說實話,這個問題確實比較難以回答,我們先來看下百度百科對算法的定義:
算法(Algorithm)是指解題方案的準確而完整的描述,是一系列解決問題的清晰指令,算法代表著用系統(tǒng)的方法描述解決問題的策略機制
簡單點說算法就是解決一個問題的步驟或者方法。比如針對去上班這個問題,我們的步驟是這樣:
首先是出門走路到地鐵站,然后坐地鐵到里公司最近的地鐵口下,最后走路到公司。這樣一個過程,可以稱之為完成這個上班任務(wù)的一個算法。但是很明顯,去上班的算法有很多種,并不止坐地鐵這一種,我們可以打的去公司、坐公交去公司等等,這樣不同的步驟也對應(yīng)著不同的算法。這些方式有好又有壞,有快也有慢,同樣算法也是一樣有好有壞有快有慢的。同一個問題,有多種解決方法,也就是多種算法,不同的算法之間也會好壞之分。
但是不管算法如何定義,它一定要具備以下五個特征才能稱之為算法:
- 有窮性:算法必須能在有限步驟之后終止。無窮無盡執(zhí)行下去,那根本不是解決問題的辦法,也就不能稱之為解決該問題的方法;
- 確切性:算法的每一步必須要有確定的含義;
- 輸入項:算法需要有輸入或者說初始條件。比如我們上班的算法,我們的初始條件就是從家出發(fā);
- 輸出項:算法必須要有一個或者多個輸出。比如我們上班的算法,輸出項就是順利到達公司;
- 可行性:算法必須是可以實現(xiàn)的步驟。那種天馬行空、無法實現(xiàn)的方法就不能稱之為算法了。如果坐著宇宙飛碟去上班,這顯然不切實際,當然也就不能成為之上班的一個算法了。
2. 為什么要學(xué)習(xí)算法
有人問在大部分的工作場景下我們都用不到算法,那么我們?yōu)槭裁催€要學(xué)習(xí)算法呢?首先,需要明確以下幾個問題:
- 工作中用不到并不代表工作中沒有用到;
- 工作中不常用并不代表面試不??迹?/li>
學(xué) Java 的同學(xué)幾乎天天都在用 HashMap
吧?但是大家有思考過存儲在 HashMap
中 key 和 value 值是究竟用什么數(shù)據(jù)結(jié)構(gòu)存儲的?當使用 get()
方法查找 value 時用的什么算法?
但是我們一般是不會考慮這種問題的,因為這些工作都由編程語言給我們已經(jīng)封裝好了,我們只需要調(diào)用,調(diào)用,再調(diào)用!
那么對于 Python 也是一樣的,我們用的 dict 等類型,它背后都是 Python 解釋器給我們做了大量工作,實現(xiàn)了各種各樣復(fù)雜的算法,給我們的使用帶來了極大的方便,也導(dǎo)致我們大部分程序員似乎在工作中幾乎看不到算法的應(yīng)用?
但是,不要忘了,我們是要追求進步的,如果你只是滿足于調(diào)用各種 API 和方法來完成工作的話這個教程對你的意義不大。不過總會有現(xiàn)有的方法滿足不了的業(yè)務(wù)場景,到那時候你該怎么辦呢?
此外,算法同樣是大廠最喜歡拿來考察候選人員能力的一個方式。社招中最喜歡考察算法編程能力公司的當屬今日頭條,許多國外的互聯(lián)網(wǎng)公司如微軟、Facebook 等甚至?xí)屇阒苯邮謱懘a。
除此以外,掌握一定的算法基礎(chǔ)有以下幾個好處:
- 鍛煉自己的思維和編程能力:保持解決問題的能力,這在工作中也是非常重要的一項技能;
- 在面試中存在一定競爭力:優(yōu)秀的編程者往往都是被大廠爭奪的對象;
- 在學(xué)習(xí)一些編程語言源碼或者操作系統(tǒng)源碼時會有深刻體會;
3. 如何學(xué)習(xí)算法?
學(xué)習(xí)基礎(chǔ)算法的方法也很簡單,就是刷題、刷題、理解后再刷題。刷題網(wǎng)站最出名的當屬 leetcode,接下來是國內(nèi)知名的就是??途W(wǎng)了。如果對自己要求高,可以考慮刷 ACM 編程題,比較有名的有 POJ、ZOJ。當你能獨立刷完上面的題目時,你已經(jīng)是一名非常厲害的算法高手了,不過刷題也會耗費大量的業(yè)余時間,要懂得適可而止,享受生活。
4. 算法的評價標準
一個算法優(yōu)劣的評價標準主要有兩個:時間復(fù)雜度和空間復(fù)雜度。
4.1 時間復(fù)雜度
程序的運行時間往往有多方面因素綜合決定,即使是同一種算法,不同的輸入對應(yīng)的運行時間可能也不相同。為針對運行時間建立一種可行、可信的評估標準,我們往往考慮輸入數(shù)據(jù)的規(guī)模,這是最關(guān)鍵的因素。
通常情況下,問題的規(guī)模越接近,相應(yīng)的計算成本也會很接近;而隨著問題的規(guī)模擴大,相應(yīng)的執(zhí)行時間也會加長。因此,隨著輸入規(guī)模的擴大,算法的執(zhí)行時間將如何增長,緩慢增長?線性增長,還是指數(shù)級增長?我們可以將算法的執(zhí)行時間和問題的規(guī)模相互映射,得到了一個關(guān)于輸入規(guī)模的函數(shù),這個就可以稱為該算法的時間復(fù)雜度。
4.2 空間復(fù)雜度
空間復(fù)雜度類似,我們將問題的規(guī)模和算法所需的存儲空間一一映射,得到的函數(shù)稱之為空間復(fù)雜度。就目前業(yè)界而言,由于存儲本身的廉價性,算法工程師們大多將算法的優(yōu)化集中在時間復(fù)雜度上,所以往往將時間復(fù)雜度當做衡量一個算法好壞的標準。當然時間復(fù)雜度低且空間復(fù)雜度也低的算法是最好的選擇,但是往往二者不能得兼,很多問題也需要具體情況具體分析。
5. 本教程學(xué)習(xí)基礎(chǔ)
本教程只需要簡單的 Python 基礎(chǔ)即可,沒有其他的任何要求。主要是能理解一些解決問題的方法,比如遞歸、動態(tài)規(guī)劃,需要一些抽象的思考能力。
6. 小結(jié)
今天我們簡單介紹了下算法的概念以及為什么要學(xué)習(xí)算法進行了介紹。最后討論了下算法的一般評價標準,主要是通過時間復(fù)雜度和空間復(fù)雜度進行衡量。今天的算法介紹就到這里了,下一節(jié)就開始算法實戰(zhàn)以及相應(yīng)的編程訓(xùn)練了,祝大家學(xué)習(xí)愉快。