天天看點

【Java】如何提高算法效率——時間複雜度和空間複雜度

【Java】如何提高算法效率——時間複雜度和空間複雜度

【寫在前邊】

當我們學習程式設計語言到達一定程度之後,就會開始注重代碼的效率,這時候就會開始研究算法這麼個東西,算法顧名思義就是計算方法,就好比你做一道數學題,有簡單的辦法也有麻煩的辦法,但是簡單的辦法不好了解,在代碼裡這個叫做可讀性差,而麻煩的辦法雖然麻煩,但是友善了解,可讀性好。在算法裡也有兩個很重要的因素,時間複雜度和空間複雜度,不同的算法有不同的特點,根據需求應用合适的算法,才是真正提高代碼效率的真谛,請往下看

【Java】如何算法效率——時間複雜度和空間複雜度

算法效率

時間複雜度

常見計算舉例

空間複雜度

算法效率分析分為兩種:第一種是時間效率,第二種是空間效率。時間效率被稱為時間複雜度,而空間效率被稱作空間複雜度。

時間複雜度主要衡量的是一個算法的運作速度,而空間複雜度主要衡量一個算法所需要的額外空間,在計算機發展的早期,計算機的存儲容量很小。是以對空間複雜度很是在乎。

但是經過計算機行業的迅速發展,計算機的存儲容量已經達到了很高的程度。是以我們如今已經不需要再特别關注一個算法的空間複雜度。

時間複雜度的概念

時間複雜度的定義:在計算機科學中,算法的時間複雜度是一個函數,它=定量描述了該算法的運作時間。一個算法執行所耗費的時間,從理論上說,是不能算出來的,隻有你把你的程式放在機器上跑起來,才能知道。但是我們需要每個算法都上機測試嗎?是可以都上機測試,但是這很麻煩,是以才有了時間複雜度這個分析方式。一個算法所花費的時間與其中語句的執行次數成正比例,算法中的基本操作的執行次數,為算法的時間複雜度。

【Java】如何提高算法效率——時間複雜度和空間複雜度

Func1 執行的基本操作次數 :

F(N)=N^2 + 2*N + 10

是以當N=10,100,1000時

N = 10

F(N) = 130

N = 100

F(N) = 10210

N = 1000

F(N) = 1002010

實際中我們計算時間複雜度時,我們其實并不一定要計算精确的執行次數,而隻需要大概執行次數,那麼這裡我們使用大O的漸進表示法。

大O符号(Big O notation):

是用于描述函數漸進行為的數學符号。

推導大O階方法:

1、用常數1取代運作時間中的所有加法常數。

2、在修改後的運作次數函數中,隻保留最高階項。

3、如果最高階項存在且不是1,則去除與這個項目相乘的常數。得到的結果就是大O階。如2×N^2,去掉常數2,結果為O (N^2)

使用大O的漸進表示法以後,Func1的時間複雜度為:O (N^2)

F(N) = 100

F(N) = 10000

F(N) = 1000000

通過上面我們會發現大O的漸進表示法去掉了那些對結果影響不大的項,簡潔明了的表示出了執行次數。

另外有些算法的時間複雜度存在最好、平均和最壞情況:

最壞情況:任意輸入規模的最大運作次數(上界)

平均情況:任意輸入規模的期望運作次數

最好情況:任意輸入規模的最小運作次數(下界)

例如:在一個長度為N數組中搜尋一個資料x

最好情況:1次找到

最壞情況:N次找到

平均情況:N/2次找到

在實際中一般情況關注的是算法的最壞運作情況,是以數組中搜尋資料時間複雜度為O(N)

【Java】如何提高算法效率——時間複雜度和空間複雜度
【Java】如何提高算法效率——時間複雜度和空間複雜度
【Java】如何提高算法效率——時間複雜度和空間複雜度
【Java】如何提高算法效率——時間複雜度和空間複雜度
【Java】如何提高算法效率——時間複雜度和空間複雜度

基本操作執行最好1次,最壞O(logN)次,時間複雜度為 O(logN) ps:logN在算法分析中表示是底數為2,對數為N。有些地方會寫成lgN。(建議通過折紙查找的方式講解logN是怎麼計算出來的)

因為二分查找每次排除掉一半的不适合值,

一次二分剩下:n/2

兩次二分剩下:n/2/2 = n/4

【Java】如何提高算法效率——時間複雜度和空間複雜度
【Java】如何提高算法效率——時間複雜度和空間複雜度

空間複雜度的概念

空間複雜度是對一個算法在運作過程中臨時占用存儲空間大小的量度 。空間複雜度不是程式占用了多少bytes的空間,因為這個也沒太大意義,是以空間複雜度算的是變量的個數。空間複雜度計算規則基本跟實踐複雜度類似,也使用大O漸進表示法。

【Java】如何提高算法效率——時間複雜度和空間複雜度
【Java】如何提高算法效率——時間複雜度和空間複雜度
【Java】如何提高算法效率——時間複雜度和空間複雜度