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