之前在面試的時候,面試官問了我一句,你知道什麼是時間複雜度和空間複雜度嗎?
這直接給我問懵了,雖然這東西天天在嘴巴上跑,但是要我用一個很通俗易懂的語言來講講,我真的不知道。
那麼我們就來說說吧:
時間複雜度和空間複雜度一般都是在算法上出現的一個衡量值,是對一個算法是否高效的一個標準。其實之前一直有個誤解,就是時間複雜度就是算法的運行週期的時間。其實這是錯誤的。並且對於算法來說,一個for就是一個算法,一個1-2-x-y=1,也是一個算法,對於我們瞭解的八大排序算法,都是算法,對於根本來說,八大排序算法都是循環本質實現的。
時間複雜度
對於時間複雜度是指的算法語句的執行次數。一個算法語句的執行次數最終都是可以通過函數f(n)來形容的。
就比如:
int i = 0;
while(i < 100){
i++;
}
這裏的i++就是算法語句,那麼其f(n) = 100 - i -1;就可以知道他的時間複雜度了。
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
System.out.println("-");
}
}
這輸出語句就是算法語句,那麼f(n)就是:f(n) = n * n = n的平方。
int i = 0;
while(i < n){
i++;
}
這裏的i++;爲算法語句,那麼f(n)就是 f(n) = n - i - 1;
那麼理解了如何將算法語句執行次數通過函數表示出來,時間複雜度一眼就可以看出來了,有以下幾條規則
(1)選取f(n)係數最大項,如果係數都負數,那麼就選擇常數,那麼時間複雜度就是常數階O(1)
(2)跟進第一條拿到係數最大項後,將係數化爲1,剩下的就是時間複雜度。
(3)一個算法可能有多條算法語句,即可能有多個循環判斷,時間複雜度的計算考慮最壞情況,即取最大值。
根據以上3個規則,那麼就可以對前三個例子分別得出對應的時間複雜度爲:
(1)O(1) (2)O(n的平方) (3)O(n)
空間複雜度
空間複雜度就是一個算法在運行過程中臨時佔用的存儲空間大小,換句話說,就是被創建次數最多的變量,他被創建了多少次,那麼這個算法的空間複雜度就是多少。eg:
for(int i = 0; i < n; i++){
int temp = i;
}
and
int temp = 0;
for(int i = 0; i < n; i++){
temp = i;
}
那麼兩者的區別很明顯的了,前者的空間複雜度就是O(n),因爲temp變量再不斷的被創建n次。那麼後者就是在循環之前就聲明好了一個變量,開闢了一個內存空間,那麼在循環中,只是不斷的將此變量的地址值指向i的內存地址。只是一個引用的操作,所以,如果算法語句中,有創建對象,那麼這個算法的時間複雜度和空間複雜度一般來說就是一致的。