前端演算法系列 演算法總結

2021-10-10 20:08:41 字數 3820 閱讀 7295

鍊錶樹

堆map

排序和搜尋

演算法設計思想

七分理解,三分記憶

技巧:三指標 反轉

回文(反轉後相同;中間劈開對稱性)

技巧:雙指標

場景:最大、最小值(使用輔助棧,當大於或小於棧頂時才push進去,然後便可取棧頂的值作為最大/小值)

煉表處理:合併、刪除

鍊錶反轉

鍊錶成環

完全二叉樹:可以不需要有兩個子結點

滿二叉樹:必須有兩個子結點

特殊的二叉樹:

1、二叉搜尋樹

特點:可以為空樹;左結點<=根結點<=右結點;有序

常見操作:搜尋、插入、刪除、遍歷(前中後序)

廣度優先遍歷:層序遍歷(棧實現)

2、平衡二叉樹:葉子節點深度差不超過1的二叉搜尋樹(所以有二叉搜尋樹的特點)

場景:構建平衡樹、驗證是否平衡樹)

索引:父結點:索引為(n-1)/2左子結點:索引2*n+1右子結點:索引2*n+2

場景:堆能高效、快速地找出最大值和最小值,時間複雜度是o(1)

找出第k個最大/小元素

集合、字典都是基於雜湊表,key都是無序且不能重複

冒泡、選擇、插入、希爾、歸併、快速(前三個o(n²),後三個o(n*logn))

少於23個專案,v8採用插入排序法,大於用快速排序(問題是不穩定性,影響重繪重排)

歸併排序是快速排序的競爭對手,火狐和safari用歸併

使用二分查詢的三個條件:

二分思想:在有序陣列裡,每次把它一分為二,看它和中間元素對比

左邊小於右邊就不斷查詢,得到中間數((左鍵+右鍵)/2),再判斷中間數和要找的target是否相等,是就表示找到,

如果沒有找到,目標數大於中間數,說明陣列是遞增的,只能去陣列右半部分查詢(mid+1);

如果目標數小於中介軟體數,說明是遞減的,只能在陣列左邊查詢(mid-1)

// 模板

functionfn(

arr, target

)else

if(arr[mid]

else

}}

將乙個問題分成多個和原問題相似的小問題,遞迴解決小問題,再將結果合併以解決原來的問題

分 -> 遞迴解決 -> 合

// 分治模板

function

divide

(problem, params, param2,

...)

// 2)準備資料和拆分問題

data =

prepare_data

(problem)

subproblems =

split_problem

(problem, data)

// 3)呼叫遞迴函式:每個子問題都調分治函式進行遞迴求解,遞迴完後存在subresult裡,相當於下探

subresult1 =

divide

(subproblems[0]

, p1,

...)

subresult2 =

divide

(subproblems[0]

, p1,

...)

subresult3 =

divide

(subproblems[0]

, p1,

...)

// 4)合併:最後將結果合併到一起

result =

process

(subresult1, subresult2, subresult3)

// 5)恢復當前層狀態:當前層狀態需要恢復

}

當乙個分治問題的子問題具有所謂的重疊或最優子結構的時候,這時候就可以去重或淘汰次優解。 如果能夠在中間每一步淘汰次優解的話,就變成了動態規劃 動態規劃 = 分治 + 最優子結構 (可以從下到上往上推)

應用場景

快速排序

子串行問題(序列就是陣列,可以利用索引)

對每個元素,考慮取和不取兩種選擇,得到對應的序列

1.凡是遇到求總類就是累加自身,求乘積就是乘以自身

求最大長度,即每次+

1: +

1求最大和,即每次加自身: +nums[i]

2.凡是遇到最,最最大最小就是math.max/min,

如果是取模1e9

+7(1000000007),不能用動態規劃了,取餘之後max函式就不能用來比大小,可以考慮貪心演算法

3. 迴圈

varlengthoflis

=function

(nums

) */

/* 2. 巢狀迴圈,跟前面所有數值比較

for(let j=0; j}

}4. 多維陣列

array.(

null

,array(3

)).map((

)=>

array(2

).fill(0

))// [[0, 0],[0, 0],[0, 0]]

array.

from(,

()=> array.

from(,

()=>0)

)// [[0, 0],[0, 0],[0, 0]]

array.

from

(new

array(3

),()

=> array.

from(,

()=>0)

)// [[0, 0],[0, 0],[0, 0]]

是一種漸進式尋找並構建問題解決方式的策略

會從乙個可能的動作開始解決問題,如果不行,就回溯並選擇另外乙個動作,直到將問題解決

即窮舉,用到dfs(回溯和樹、遞迴都差不多,只是處理完每一層,都要初始化,回到根節點)

dfs

(level

)

陣列方法

1. push直接改變當前陣列;concat不改變當前陣列

2. concat、slice是淺拷貝,不會改變當前陣列;

比如:res.

push

(curr.

slice()

)而不是簡單的 res.

push

(curr) ,curr是全域性的,會被隨時更新,所以要拷貝乙份

剪枝:比如八皇后問題,只要列、撇、捺被佔了,就馬上進行剪枝(判斷當前格仔不能填皇后)

期盼通過每個階段的區域性最優選擇,從而達到全域性的最優,結果並不一定最優

,可以用if

(!arr.length)來表示arr為空時做什麼

2. 字串轉數字時,乘以1

'2'*1=

23. 建立二維陣列

let arr=[1

,3,4

,5]let b =

array

(arr.length)

.fill(0

).map(()

=>

array(2

+1).

fill(0

))// [[0, 0, 0],[0, 0, 0],[0, 0, 0],[0, 0, 0]]

前端演算法系列 排序

排序演算法 平均時間複雜度 最壞時間複雜度 空間複雜度 是否穩定 氣泡排序 o n o n o 1 是選擇排序 o n o n o 1 不是直接插入排序 o n o n o 1 是快速排序 o nlogn o n o logn 不是希爾排序 o nlogn o n s o 1 不是冒泡 選擇 直接 ...

前端演算法系列 搜尋

遍歷陣列,找到跟目標相等的元素,就返回它的下標,遍歷結束後,沒找到就返回 1 時間複雜度 o n 迴圈 array.prototype.sequentialsearch function item return 1 const arr 5 4,3 2,1 arr.sequentialsearch 3...

java演算法系列

棧的概念 棧是一種特殊的線性表,堆疊的資料元素以及資料元素之間的關係和線性表是完全一樣的。差別是線性表是在任意位置進行插入和刪除操作,棧是只允許在固定的一端進行插入和刪除,棧的插入和刪除只允許在棧頂,棧的插入和刪除通常稱為進棧和出棧。資料集合 每個資料元素的資料型別可以是任意的型別 操作的集合 進棧...