# 数据结构与算法 ## 1. 链表 ### 反转链表 ```js function reverseList(head) { let prev = null, curr = head; while (curr) { const next = curr.next; curr.next = prev; prev = curr; curr = next; } return prev; } ``` ### 环形链表判断 ```js function hasCycle(head) { let slow = head, fast = head; while (fast?.next) { slow = slow.next; fast = fast.next.next; if (slow === fast) return true; } return false; } ``` ### 合并有序链表 ```js function mergeTwoLists(l1, l2) { const dummy = { next: null }; let curr = dummy; while (l1 && l2) { if (l1.val <= l2.val) { curr.next = l1; l1 = l1.next; } else { curr.next = l2; l2 = l2.next; } curr = curr.next; } curr.next = l1 || l2; return dummy.next; } ``` --- ## 2. 二叉树 ### 遍历(前中后序) ```js // 前序:根-左-右 const preorder = (root, res = []) => { if (!root) return res; res.push(root.val); preorder(root.left, res); preorder(root.right, res); return res; }; // 中序:左-根-右 const inorder = (root, res = []) => { if (!root) return res; inorder(root.left, res); res.push(root.val); inorder(root.right, res); return res; }; // 后序:左-右-根 const postorder = (root, res = []) => { if (!root) return res; postorder(root.left, res); postorder(root.right, res); res.push(root.val); return res; }; ``` ### 求最大深度 ```js const maxDepth = root => { if (!root) return 0; return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); }; ``` ### 路径和 ```js function hasPathSum(root, targetSum) { if (!root) return false; if (!root.left && !root.right) return targetSum === root.val; return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val); } ``` --- ## 3. 栈与队列 ### 用栈实现队列 ```js class MyQueue { constructor() { this.inStack = []; this.outStack = []; } push(x) { this.inStack.push(x); } pop() { if (!this.outStack.length) { while (this.inStack.length) this.outStack.push(this.inStack.pop()); } return this.outStack.pop(); } peek() { if (!this.outStack.length) { while (this.inStack.length) this.outStack.push(this.inStack.pop()); } return this.outStack[this.outStack.length - 1]; } empty() { return !this.inStack.length && !this.outStack.length; } } ``` ### 有效的括号 ```js function isValid(s) { const map = { ')': '(', ']': '[', '}': '{' }; const stack = []; for (const c of s) { if (map[c]) { if (stack.pop() !== map[c]) return false; } else { stack.push(c); } } return !stack.length; } ``` --- ## 4. 哈希表 ### 两数之和 ```js function twoSum(nums, target) { const map = new Map(); for (let i = 0; i < nums.length; i++) { const diff = target - nums[i]; if (map.has(diff)) return [map.get(diff), i]; map.set(nums[i], i); } return []; } ``` ### 字母异位词分组 ```js function groupAnagrams(strs) { const map = new Map(); for (const s of strs) { const key = [...s].sort().join(''); map.set(key, (map.get(key) || []).concat(s)); } return [...map.values()]; } ``` --- ## 5. 排序算法 ### 快速排序 ```js function quickSort(arr) { if (arr.length <= 1) return arr; const pivot = arr[Math.floor(arr.length / 2)]; const left = arr.filter(x => x < pivot); const middle = arr.filter(x => x === pivot); const right = arr.filter(x => x > pivot); return [...quickSort(left), ...middle, ...quickSort(right)]; } ``` ### 归并排序 ```js function mergeSort(arr) { if (arr.length <= 1) return arr; const mid = Math.floor(arr.length / 2); const left = mergeSort(arr.slice(0, mid)); const right = mergeSort(arr.slice(mid)); return merge(left, right); } function merge(left, right) { const result = []; let i = 0, j = 0; while (i < left.length && j < right.length) { result.push(left[i] < right[j] ? left[i++] : right[j++]); } return result.concat(left.slice(i), right.slice(j)); } ``` --- ## 6. 二分查找 ### 基础二分查找 ```js function binarySearch(arr, target) { let left = 0, right = arr.length - 1; while (left <= right) { const mid = Math.floor((left + right) / 2); if (arr[mid] === target) return mid; arr[mid] < target ? (left = mid + 1) : (right = mid - 1); } return -1; } ``` ### 旋转数组查找 ```js function searchRotated(nums, target) { let left = 0, right = nums.length - 1; while (left <= right) { const mid = Math.floor((left + right) / 2); if (nums[mid] === target) return mid; // 左半边有序 if (nums[left] <= nums[mid]) { if (target >= nums[left] && target < nums[mid]) right = mid - 1; else left = mid + 1; } else { // 右半边有序 if (target > nums[mid] && target <= nums[right]) left = mid + 1; else right = mid - 1; } } return -1; } ```