
大家好,我是小丞同學,一名大二的前端愛好者
這篇文章是資料結構與算法專欄的第一篇博文
非常感謝你的閱讀,不對的地方歡迎指正
願你忠于自己,熱愛生活
知識點搶先看
算法基礎
計算時間複雜度
計算空間複雜度
資料結構和算法的學習指南
文末有驚喜噢~
專欄簡介
按照慣例,每個專欄的第一篇文章都會簡單的介紹一下這個專欄的内容,以及未來的更文計劃
本專欄 【化解資料結構】,将在這裡總結自己學習資料結構和算法的學習筆記,從這篇算法入門開始,未來更文将涉及棧、隊列、連結清單、堆、樹、圖…等資料結構,以及經典排序算法,算法設計思想等進階算法…,同時将會結合 LeetCode 題目對每篇文章進行鞏固和提升,歡迎大家關注本專欄或添加作者本文聯系方式,一起努力,一起刷題,一起進步
(圖檔來源于慕課網截圖)
引言
在正式寫這個之前,先來講講為什麼要學資料結構和算法?
為了計算出最優解
這是我的答案,當我打開 LeetCode 第一題兩數之和的送出記錄時,我發現自己半年前的代碼,耗時 240ms,記憶體占用 40多mb 時,我感受到了它的魅力
在最新的代碼中,我采用了 map 的容器,通過 has 方法替代了先前采用的 indexof 方法,從查到的資料來看,map 的查找的時間複雜度為 O(1) ,indexOf 為 O(n) ,在 map 的底層實作中采用了哈希表的資料結構,極大的優化了查找的複雜度
接下來我們來看看如何計算時間、空間複雜度!
一. 大 O 表示法
關于複雜度的計算,我們采用的是 大 O 表示法 ,它用來描述算法性能和複雜程度
常見的表示
符号大O标記法 名稱
O(1) 常數
O(log N) 對數
O(N) 線性
O(N log N) 對數多項式
O(N^2) 二次
O(2^N) 指數
O(N!) 階乘
大 O 表示法一般考慮的是 CPU 占用時間,它可以粗略的了解代碼運作的時間效率
例如
function test(num){
return ++num;
}
我們調用這個函數一次,執行時間是 t ,我們再調用一次,執行時間還是 t,和傳入的參數無關, test 函數的性能都一樣,是以它的複雜度為 O(1)
當循環 n 次時,就是 O(n)
二. 時間複雜度
大 O 表示法表明的是該段代碼執行時間随資料規模增大的變化趨勢,它的特點是
隻關注量級最大的時間複雜度
常見的時間複雜度量級 O(1) < O(logn) < O(n) < O(n^2)
對于 O(2)、O(3) 這些,我們都叫做 O(1) 常數級
例如:
1. O(1)
let i = 0;
i += 1;
// 每次執行代碼隻執行一次 O(1)
這段代碼每次隻執行一次,是以為 O(1)
2. O(n)
for (let j = 0; j < n; j++) {
console.log(j);
}
再上面這段代碼中,我們每次都需要執行 n 次的 log ,是以我們可以把它看作 O(n)
同樣的我們再來看一個
let i = 0;
i += 1;
for (let j = 0; j < navigator; j++) {
console.log(j);
}
這種代碼我們經常寫,前面是我們剛剛計算的 O(1),後面是 O(n) ,它們并行排列,時間複雜度相加,取最大的那個
是以它的時間複雜度同樣是 O(n)
3. O(log(n))
while (i < n) {
console.log(i);
i *= 2;
}
對于 log(n) 的情況,在個時間複雜度是很好的,當然 O(1) 是最好的,但是在解題的時候,如果能優化到 log(n) 也是很不錯的了
那它是如何計算的呢?
我們可以看到,這裡采用了 變量i來控制循環的終止,每次循環體中,都需要 2 * i 的操作
是以對于時間複雜度的計算 2^t = n 解得 t = log(n)
4. O(n^2)
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
console.log(i);
}
}
對于這種嵌套排列,時間複雜度是 n^2 ,外面一層 n ,裡面一層 n 乘一下就是 n^2,冒泡排序的時間複雜度就是 O(n^2)
關于時間複雜度就介紹這麼多,其他的思路都差不多
三、空間複雜度
空間複雜度表示的是:存儲空間随資料規模的增長趨勢,在 LeetCode 中最直接的反應就是記憶體消耗
let i = 0;
在這裡我們申請了單個變量的記憶體空間,為 O(1)
let arr = []
for(let i = 0;i < n;i++) {
arr.push(i)
}
像這樣的一個數組,并給它填滿值,n 越大,它需要配置設定的空間就越多,它的空間複雜度就是 O(n)
3. O(n^2)
int arr = [][]// 周遊指派
聲明一個二維數組,填滿值,它的空間複雜度就是 O(n^2) ,你可以了解為一個矩陣,n*n 為 n^2
總結
複雜度計算按最高階來計算
時間、空間複雜度描述的都是随資料規模的變化趨勢
時間複雜度的重點在于循環嵌套
空間複雜度關注于記憶體