本篇文章收錄於專輯:http://dwz.win/HjK,點擊解鎖更多數據結構與算法的知識。java
你好,我是彤哥,一個天天爬二十六層樓還不忘讀源碼的硬核男人。算法
上一節,咱們一塊兒學習了複雜度分析的套路和常見的複雜度。數組
可是,咱們的案例基本都是以時間複雜度爲主,不多接觸到空間複雜度。數據結構
那麼,到底什麼纔是真正的空間複雜度呢?在空間與時間發生衝突時又該如何權衡呢?架構
本節,咱們就來解決這兩個問題。學習
如今有一個算法是這樣的,給定一個數組,將數組中每一個元素都乘以2返回,我實現了下面兩種形式:code
private static int[] multi1(int[] array) { int[] newArray = new int[array.length]; for (int i = 0; i < array.length; i++) { newArray[i] = array[i] * 2; } return newArray; } private static int[] multi2(int[] array) { for (int i = 0; i < array.length; i++) { array[i] = array[i] * 2; } return array; }
暫且不論這兩個算法孰好孰壞,你來猜猜他們的空間複雜度各是多少?blog
你可能會說第一個算法的空間複雜度爲O(n),第二個算法的空間複雜度爲O(1)。排序
錯!兩個算法的空間複雜度都是O(n)。get
也不能說你徹底錯了,由於大部分書籍或者資料都弄錯了。
是時候瞭解真正的空間複雜度了。
空間複雜度,是指一個算法運行的過程佔用的空間,這個空間包括輸入參數的佔用空間和額外申請的空間。
因此,針對上面兩個算法:
能夠看到,使用空間複雜度很難判斷這兩個算法的好壞,因此,誕生了另外一個概念——額外空間複雜度。
額外空間複雜度,是指一個算法運行過程當中額外申請的空間。
使用額外空間複雜度,針對上面兩個算法:
彷佛沒見過有O(0)這種寫法。
能夠看到,使用額外空間複雜度可以很輕易地判斷兩個算法的好壞(從空間佔用的角度)。
因此,是時候糾正錯誤的概念了,之後與人交流的時候請使用「額外空間複雜度」這個概念。
時間與空間每每是一組糾纏在一塊兒的概念,就像不少小說中寫的同樣,主角最終領悟了時空法則,成爲了最強者,小說結束。
在數據結構與算法中也是同樣,時間與空間每每同時出現,並且常常朝着相反的方向運動。
好比,對於排序算法:
因此,有兩種思想:以時間換空間,以空間換時間。
那麼,哪一種算法更好呢?
我認爲,若是有時間、空間同時比較小的爲最好,退而求其次,我選擇以空間換時間,畢竟,隨着計算機硬件技術地不斷髮展,空間愈來愈不值錢,而時間卻愈來愈值錢,因此,以空間換時間也是一種經常使用的思想,在咱們後續的課程中會出現大量以空間換時間的案例。
想知道冒泡排序和歸併排序算法的複雜度如何計算嗎?來呀,關注我吧。
本節,咱們從一個小例子入手,分析了兩種算法的空間複雜度,並引出空間複雜度的真身——額外空間複雜度,最後,經過對比冒泡排序和歸併排序的時間複雜度和空間複雜度,得出了以空間換時間的思想。
到這裏,關於複雜度相關的章節就寫完了,從下一節開始,咱們將進入經常使用數據結構與算法的學習中,敬請期待。
P.S. 下週將進行晉升答辯,會停更幾天,敬請諒解。
關注公號主「彤哥讀源碼」,解鎖更多源碼、基礎、架構知識。