forked from ligecarryme/algorithm-pattern-JavaScript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathanki_linkedlist.csv
More file actions
We can make this file beautiful and searchable if this error is corrected: Illegal quoting in line 1.
353 lines (353 loc) · 18.9 KB
/
anki_linkedlist.csv
File metadata and controls
353 lines (353 loc) · 18.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<h3>🔗 206. 反转链表</h3><p><b>难度:</b> Easy | <b>标签:</b> 必背</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">给你单链表的头节点 `head` ,请你反转链表,并返回反转后的链表。</blockquote><p><a href="https://leetcode-cn.com/problems/reverse-linked-list/">🔗 LeetCode 链接</a></p> <pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var reverseList = function(head) {<br> let prev = null;<br> let cur = head;<br> while (cur !== null) {<br> let next = cur.next;<br> cur.next = prev;<br> prev = cur;<br> cur = next;<br> }<br> return prev;<br>};</code></pre>
<h3>🔗 92. 反转链表 II</h3><p><b>难度:</b> Medium | <b>标签:</b> 区间反转</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">给你单链表的头节点 `head` 和两个整数 `left` 和 `right` ,请你反转从位置 `left` 到位置 `right` 的链表节点,返回反转后的链表。</blockquote><p><a href="https://leetcode-cn.com/problems/reverse-linked-list-ii/">🔗 LeetCode 链接</a></p> <pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var reverseBetween = function(head, m, n) {<br> let dummy = new ListNode(-1);<br> dummy.next = head;<br> let pre = dummy;<br> for (let i = 1; i < m; i++) {<br> pre = pre.next;<br> }<br> let cur = pre.next;<br> for (let i = 0; i < n - m; i++) {<br> let next = cur.next;<br> cur.next = next.next;<br> next.next = pre.next;<br> pre.next = next;<br> }<br> return dummy.next;<br>};</code></pre>
<h3>🔗 25. K 个一组翻转链表</h3><p><b>难度:</b> Hard | <b>标签:</b> 面试常客</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">给你一个链表,每 `k` 个节点一组进行翻转,请你返回翻转后的链表。</blockquote><p><a href="https://leetcode-cn.com/problems/reverse-nodes-in-k-group/">🔗 LeetCode 链接</a></p> <pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var reverseKGroup = function(head, k) {<br> let cur = head;<br> let count = 0;<br> // 探测是否够 k 个<br> while (cur !== null && count !== k) {<br> cur = cur.next;<br> count++;<br> }<br> if (count === k) {<br> // 反转这 k 个节点<br> let prev = null;<br> let node = head;<br> for (let i = 0; i < k; i++) {<br> let next = node.next;<br> node.next = prev;<br> prev = node;<br> node = next;<br> }<br> // 递归连接<br> head.next = reverseKGroup(cur, k);<br> return prev;<br> }<br> return head;<br>};</code></pre>
<h3>🔗 21. 合并两个有序链表</h3><p><b>难度:</b> Easy</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">将两个升序链表合并为一个新的升序链表并返回。</blockquote><p><a href="https://leetcode-cn.com/problems/merge-two-sorted-lists/">🔗 LeetCode 链接</a></p> <p><b>解法 1:</b></p><pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>// 迭代法<br>var mergeTwoLists = function(l1, l2) {<br> let dummy = new ListNode(-1);<br> let pre = dummy;<br> while (l1 !== null && l2 !== null) {<br> if (l1.val <= l2.val) {<br> pre.next = l1;<br> l1 = l1.next;<br> } else {<br> pre.next = l2;<br> l2 = l2.next;<br> }<br> pre = pre.next;<br> }<br> pre.next = l1 === null ? l2 : l1;<br> return dummy.next;<br>};</code></pre><hr><p><b>解法 2:</b></p><pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>//递归<br>var mergeTwoLists = function(l1, l2) {<br> if(l1 === null){<br> return l2;<br> }else if(l2 === null){<br> return l1;<br> }else if(l1.val <= l2.val){<br> l1.next = mergeTwoLists(l1.next,l2);<br> return l1;<br> }else{<br> l2.next = mergeTwoLists(l1,l2.next);<br> return l2;<br> }<br>};</code></pre>
<h3>🔗 23. 合并K个排序链表</h3><p><b>难度:</b> Hard | <b>标签:</b> 堆/归并</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中。</blockquote><p><a href="https://leetcode-cn.com/problems/merge-k-sorted-lists/">🔗 LeetCode 链接</a></p> <p><b>解法 1:</b></p><pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var mergeKLists = function(lists) {<br> if (lists.length === 0) return null;<br> return solve(lists, 0, lists.length - 1);<br>};<br><br>function solve(lists, left, right) {<br> if (left === right) return lists[left];<br> let mid = Math.floor((left + right) / 2);<br> let l1 = solve(lists, left, mid);<br> let l2 = solve(lists, mid + 1, right);<br> return mergeTwoLists(l1, l2);<br>}<br><br>function mergeTwoLists(l1, l2) {<br> let dummy = new ListNode(-1);<br> let pre = dummy;<br> while (l1 && l2) {<br> if (l1.val < l2.val) {<br> pre.next = l1;<br> l1 = l1.next;<br> } else {<br> pre.next = l2;<br> l2 = l2.next;<br> }<br> pre = pre.next;<br> }<br> pre.next = l1 || l2;<br> return dummy.next;<br>}</code></pre><hr><p><b>解法 2:</b></p><pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var mergeKLists = function(lists) {<br> let dummy = new ListNode(-1);<br> let p = dummy;<br> let pq = new MinHeap((a, b) => a.val < b.val); // 伪代码:假设有最小堆<br><br> for (let head of lists) {<br> if (head) pq.push(head);<br> }<br><br> while (!pq.isEmpty()) {<br> let node = pq.pop();<br> p.next = node;<br> if (node.next) pq.push(node.next);<br> p = p.next;<br> }<br> return dummy.next;<br>};</code></pre>
<h3>🔗 148. 排序链表</h3><p><b>难度:</b> Medium | <b>标签:</b> 归并排序</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">给你链表的头结点 `head` ,请将其按升序排列并返回排序后的链表(要求 $O(n \log n)$ 时间复杂度和 $O(1)$ 空间复杂度)。</blockquote><p><a href="https://leetcode-cn.com/problems/sort-list/">🔗 LeetCode 链接</a></p> <pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var sortList = function(head) {<br> return mergeSort(head);<br>};<br><br>const mergeSort = head => {<br> if (head === null || head.next === null) {<br> return head;<br> }<br> let slow = head;<br> let fast = head.next.next;<br> while (fast !== null && fast.next !== null) {<br> slow = slow.next;<br> fast = fast.next.next;<br> }<br> let mid = slow.next;<br> slow.next = null;<br> let left = mergeSort(head);<br> let right = mergeSort(mid);<br> return merge(left, right);<br>}<br><br>const merge = (l1, l2) => {<br> let dummy = new ListNode(-1);<br> let pre = dummy;<br> while (l1 !== null && l2 !== null) {<br> if (l1.val < l2.val) {<br> pre.next = l1;<br> l1 = l1.next;<br> } else {<br> pre.next = l2;<br> l2 = l2.next;<br> }<br> pre = pre.next;<br> }<br> pre.next = l1 !== null ? l1 : l2;<br> return dummy.next;<br>}</code></pre>
<h3>🔗 补充题1. 排序奇升偶降链表</h3><p><b>难度:</b> Medium</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">给定一个奇数位升序,偶数位降序的链表,将其排序为升序。 (思路:拆分、反转偶数链表、合并)</blockquote><p><a href="https://leetcode-cn.com/problems/sort-list/">🔗 LeetCode 链接</a></p> <p style="color:#888;">暂无代码答案,请参考 LeetCode 官方题解</p>
<h3>🔗 141. 环形链表</h3><p><b>难度:</b> Easy | <b>标签:</b> 判圈</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">给你一个链表的头节点 `head` ,判断链表中是否有环。</blockquote><p><a href="https://leetcode-cn.com/problems/linked-list-cycle/">🔗 LeetCode 链接</a></p> <pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var hasCycle = function(head) {<br> let slow = head;<br> let fast = head;<br> while (fast !== null && fast.next !== null) {<br> slow = slow.next;<br> fast = fast.next.next;<br> if (slow === fast) return true;<br> }<br> return false;<br>};</code></pre>
<h3>🔗 142. 环形链表 II</h3><p><b>难度:</b> Medium | <b>标签:</b> 找入口</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">给定一个链表,返回链表开始入环的第一个节点。如果链表无环,则返回 `null`。</blockquote><p><a href="https://leetcode-cn.com/problems/linked-list-cycle-ii/">🔗 LeetCode 链接</a></p> <pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var detectCycle = function(head) {<br> let slow = head;<br> let fast = head;<br> while (fast !== null && fast.next !== null) {<br> slow = slow.next;<br> fast = fast.next.next;<br> if (slow === fast) {<br> slow = head;<br> while (slow !== fast) {<br> slow = slow.next;<br> fast = fast.next;<br> }<br> return slow;<br> }<br> }<br> return null;<br>};</code></pre>
<h3>🔗 160. 相交链表</h3><p><b>难度:</b> Easy</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">给你两个单链表的头节点 `headA` 和 `headB` ,请你找出并返回两个单链表相交的起始节点。</blockquote><p><a href="https://leetcode-cn.com/problems/intersection-of-two-linked-lists/">🔗 LeetCode 链接</a></p> <pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var getIntersectionNode = function(headA, headB) {<br> if (headA === null || headB === null) return null;<br> let pA = headA;<br> let pB = headB;<br> <br> // 只要不相等就继续走<br> while (pA !== pB) {<br> // 走完 A 就走 B,走完 B 就走 A<br> pA = pA === null ? headB : pA.next;<br> pB = pB === null ? headA : pB.next;<br> }<br> <br> return pA;<br>};</code></pre>
<h3>🔗 19. 删除链表的倒数第N个节点</h3><p><b>难度:</b> Medium</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">给你一个链表,删除链表的倒数第 `n` 个结点,并且返回链表的头结点。</blockquote><p><a href="https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/">🔗 LeetCode 链接</a></p> <p style="color:#888;">暂无代码答案,请参考 LeetCode 官方题解</p>
<h3>🔗 剑指 Offer 22. 链表中倒数第k个节点</h3><p><b>难度:</b> Easy</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">输入一个链表,输出该链表中倒数第 `k` 个节点。</blockquote><p><a href="https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/">🔗 LeetCode 链接</a></p> <p style="color:#888;">暂无代码答案,请参考 LeetCode 官方题解</p>
<h3>🔗 143. 重排链表</h3><p><b>难度:</b> Medium | <b>标签:</b> 中点+反转+合并</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">给定一个单链表 $L_0 \to L_1 \to \dots \to L_{n-1} \to L_n$ ,将其重新排列后变为: $L_0 \to L_n \to L_1 \to L_{n-1} \to L_2 \to L_{n-2} \to \dots$</blockquote><p><a href="https://leetcode-cn.com/problems/reorder-list/">🔗 LeetCode 链接</a></p> <pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var reorderList = function(head) {<br> if (head === null) return;<br> let slow = head;<br> let fast = head;<br> while (fast !== null && fast.next !== null) {<br> slow = slow.next;<br> fast = fast.next.next;<br> }<br> <br> let prev = null;<br> let cur = slow.next;<br> slow.next = null;<br> while (cur !== null) {<br> let next = cur.next;<br> cur.next = prev;<br> prev = cur;<br> cur = next;<br> }<br> <br> let head1 = head;<br> let head2 = prev;<br> while (head1 !== null && head2 !== null) {<br> let next1 = head1.next;<br> let next2 = head2.next;<br> head1.next = head2;<br> head1 = next1;<br> head2.next = next1; // 修正逻辑:head1->head2->next1<br> head2 = next2;<br> }<br>};</code></pre>
<h3>🔗 2. 两数相加</h3><p><b>难度:</b> Medium</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的。请你将两个数相加。</blockquote><p><a href="https://leetcode-cn.com/problems/add-two-numbers/">🔗 LeetCode 链接</a></p> <p><b>解法 1:</b></p><pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var genericSolution = function(head) {<br> let dummy = new ListNode(-1); // 哨兵节点<br> dummy.next = head;<br> let pre = dummy; <br> let cur = head;<br> while (cur !== null) {<br> // 逻辑处理...<br> cur = cur.next;<br> }<br> return dummy.next;<br>};</code></pre><hr><p><b>解法 2:</b></p><pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var findMiddle = function(head) {<br> let slow = head;<br> let fast = head.next; <br> while (fast !== null && fast.next !== null) {<br> slow = slow.next;<br> fast = fast.next.next;<br> }<br> return slow; <br>};</code></pre><hr><p><b>解法 3:</b></p><pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var reverseList = function(head) {<br> let prev = null;<br> let curr = head;<br> while (curr !== null) {<br> let nextTemp = curr.next; <br> curr.next = prev; <br> prev = curr; <br> curr = nextTemp;<br> }<br> return prev; <br>};</code></pre>
<h3>🔗 146. LRU缓存机制</h3><p><b>难度:</b> Medium | <b>标签:</b> 双向链表+哈希</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">设计并实现一个满足 LRU (最近最少使用) 缓存约束的数据结构。</blockquote><p><a href="https://leetcode-cn.com/problems/lru-cache/">🔗 LeetCode 链接</a></p> <pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>/**<br> * @param {number} capacity<br> */<br>var LRUCache = function(capacity) {<br> this.capacity = capacity;<br> this.map = new Map(); // key -> node<br> this.head = new ListNode(-1, -1); // 虚拟头<br> this.tail = new ListNode(-1, -1); // 虚拟尾<br> this.head.next = this.tail;<br> this.tail.prev = this.head;<br>};<br><br>function ListNode(key, val) {<br> this.key = key;<br> this.val = val;<br> this.prev = null;<br> this.next = null;<br>}<br><br>/** <br> * @param {number} key<br> * @return {number}<br> */<br>LRUCache.prototype.get = function(key) {<br> if (!this.map.has(key)) return -1;<br> const node = this.map.get(key);<br> this.moveToHead(node); // 访问后移到头部<br> return node.val;<br>};<br><br>/** <br> * @param {number} key <br> * @param {number} value<br> * @return {void}<br> */<br>LRUCache.prototype.put = function(key, value) {<br> if (this.map.has(key)) {<br> const node = this.map.get(key);<br> node.val = value;<br> this.moveToHead(node);<br> } else {<br> if (this.map.size === this.capacity) {<br> const lastNode = this.tail.prev;<br> this.removeNode(lastNode);<br> this.map.delete(lastNode.key);<br> }<br> const newNode = new ListNode(key, value);<br> this.addNodeToHead(newNode);<br> this.map.set(key, newNode);<br> }<br>};<br><br>// 辅助函数:将节点移到头部<br>LRUCache.prototype.moveToHead = function(node) {<br> this.removeNode(node);<br> this.addNodeToHead(node);<br>};<br><br>// 辅助函数:删除节点<br>LRUCache.prototype.removeNode = function(node) {<br> node.prev.next = node.next;<br> node.next.prev = node.prev;<br>};<br><br>// 辅助函数:在头部插入节点<br>LRUCache.prototype.addNodeToHead = function(node) {<br> node.next = this.head.next;<br> node.prev = this.head;<br> this.head.next.prev = node;<br> this.head.next = node;<br>};</code></pre>
<h3>🔗 82. 删除排序链表中的重复元素 II</h3><p><b>难度:</b> Medium</p><blockquote style="background:#f0f0f0;padding:10px;border-left:4px solid #007bff;margin:10px 0;">给定一个已排序的链表的头 `head` ,删除所有含有重复数字的节点,只保留原始链表中未重复出现的数字。</blockquote><p><a href="https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/">🔗 LeetCode 链接</a></p> <pre style="background:#1e1e1e;color:#d4d4d4;padding:10px;border-radius:5px;overflow-x:auto;font-family:monospace;"><code>var deleteDuplicates = function(head) {<br> let dummy = new ListNode(-1);<br> dummy.next = head;<br> let pre = dummy;<br> while (pre.next !== null && pre.next.next !== null) {<br> if (pre.next.val === pre.next.next.val) {<br> let val = pre.next.val;<br> while (pre.next !== null && pre.next.val === val) {<br> pre.next = pre.next.next;<br> }<br> } else {<br> pre = pre.next;<br> }<br> }<br> return dummy.next;<br>}</code></pre>