觀感度:🌟🌟🌟🌟🌟javascript
口味:蒜蓉荷蘭豆前端
烹飪時間:8minjava
本文已收錄在前端食堂同名倉庫
Github
github.com/Geekhyt,歡迎光臨食堂,若是以爲酒菜還算可口,賞個 Star 對食堂老闆來講是莫大的鼓勵。
數組想必你們都很熟悉,幾乎咱們天天都會操做它。那麼咱們就來對比數組來學習鏈表,首先要明確的是,鏈表和數組的底層存儲結構不一樣,數組要求存儲在一塊連續的內存中,而鏈表是經過指針將一組零散的內存塊串聯起來。可見鏈表對內存的要求下降了,可是隨機訪問的性能就沒有數組好了,須要 O(n) 的時間複雜度。node
下圖中展現了單鏈表及單鏈表的添加和刪除操做,其實鏈表操做的本質就是處理鏈表結點之間的指針。git
在刪除鏈表結點的操做中,咱們只須要將須要刪除結點的前驅結點的 next 指針,指向其後繼便可。這樣,當前被刪除的結點就被丟棄在內存中,等待着它的是被垃圾回收器清除。github
爲了更便於你理解,鏈表能夠類比現實生活中的火車,火車的每節車箱就是鏈表的一個個結點。車箱之間相互鏈接,能夠添加或者移除掉。春運時,客運量比較大,列車通常會加掛車箱。數組
鏈表的結點結構由數據域和指針域組成,在 JavaScript 中,以嵌套的對象形式實現。性能
{ // 數據域 val: 1, // 指針域 next: { val:2, next: ... } }
掌握了鏈表的基礎知識後,咱們拿幾道鏈表的 LeetCode 真題練練手,點擊題目標題便可跳轉到相關題目的描述頁面。學習
N+M 是兩條鏈表的長度spa
const mergeTwoLists = function (l1, l2) { if (l1 === null) { return l2; } if (l2 === null) { return l1; } if (l1.val < l2.val) { l1.next = mergeTwoLists(l1.next, l2); return l1; } else { l2.next = mergeTwoLists(l1, l2.next); return l2; } };
const hasCycle = function(head) { if (!head || !head.next) { return false; } let fast = head.next; let slow = head; while (fast !== slow) { if (!fast || !fast.next) { return false; } fast = fast.next.next; slow = slow.next; } return true; };
const hasCycle = function(head) { while (head) { if (head.flag) { return true; } else { head.flag = true; head = head.next; } } return false; }
const reverseList = function(head) { let prev = null; let curr = head; while (curr !== null) { let next = curr.next; curr.next = prev; prev = curr; curr = next; } return prev; };
const removeNthFromEnd = function(head, n) { let prev = new ListNode(0); prev.next = head; let fast = prev; let slow = prev; while (n--) { fast = fast.next; } while (fast && fast.next) { fast = fast.next; slow = slow.next; } slow.next = slow.next.next; return prev.next; };
const middleNode = function(head) { let fast = head; let slow = head; while (fast && fast.next) { slow = slow.next; fast = fast.next.next; } return slow; };
1.看到這裏了就點個贊支持下吧,你的贊是我創做的動力。
2.關注公衆號前端食堂,你的前端食堂,記得按時吃飯!
3.本文已收錄在前端食堂Github
github.com/Geekhyt,求個小星星,感謝Star。