首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >LeetCode 高频 50 题:最优解笔记(附题解)

LeetCode 高频 50 题:最优解笔记(附题解)

作者头像
大熊计算机
发布2025-07-15 13:58:43
发布2025-07-15 13:58:43
7660
举报
文章被收录于专栏:C博文C博文

LeetCode 高频 50 题:最优解笔记

高频 50 题题目列表

  1. 两数之和 (Two Sum)
  2. 反转链表 (Reverse Linked List)
  3. 有效的括号 (Valid Parentheses)
  4. 买卖股票的最佳时机 (Best Time to Buy and Sell Stock)
  5. 二叉树的层序遍历 (Binary Tree Level Order Traversal)
  6. 最大子序和 (Maximum Subarray)
  7. 爬楼梯 (Climbing Stairs)
  8. 三数之和 (3Sum)
  9. 合并两个有序链表 (Merge Two Sorted Lists)
  10. 二叉树的最近公共祖先 (Lowest Common Ancestor of a Binary Tree)
  11. 环形链表 (Linked List Cycle)
  12. 相交链表 (Intersection of Two Linked Lists)
  13. 全排列 (Permutations)
  14. 岛屿数量 (Number of Islands)
  15. 最长连续序列 (Longest Consecutive Sequence)
  16. 单词搜索 (Word Search)
  17. 最小路径和 (Minimum Path Sum)
  18. 搜索旋转排序数组 (Search in Rotated Sorted Array)
  19. 接雨水 (Trapping Rain Water)
  20. 最长有效括号 (Longest Valid Parentheses)
  21. 数组中的第K个最大元素 (Kth Largest Element in an Array)
  22. 除自身以外数组的乘积 (Product of Array Except Self)
  23. 滑动窗口最大值 (Sliding Window Maximum)
  24. 寻找重复数 (Find the Duplicate Number)
  25. LRU缓存机制 (LRU Cache)
  26. 盛最多水的容器 (Container With Most Water)
  27. 合并区间 (Merge Intervals)
  28. 最长无重复子串 (Longest Substring Without Repeating Characters)
  29. 最长回文子串 (Longest Palindromic Substring)
  30. 前 K 个高频元素 (Top K Frequent Elements)
  31. 编辑距离 (Edit Distance)
  32. 最大矩形 (Maximal Rectangle)
  33. 二叉树中的最大路径和 (Binary Tree Maximum Path Sum)
  34. 实现 Trie (前缀树) (Implement Trie (Prefix Tree))
  35. 回文链表 (Palindrome Linked List)
  36. 二叉树的锯齿形层序遍历 (Binary Tree Zigzag Level Order Traversal)
  37. 环形链表 II (Linked List Cycle II)
  38. 合并K个升序链表 (Merge k Sorted Lists)
  39. 最长上升子序列 (Longest Increasing Subsequence)
  40. 打家劫舍 (House Robber)
  41. 打家劫舍 III (House Robber III)
  42. 搜索二维矩阵 II (Search a 2D Matrix II)
  43. 完全平方数 (Perfect Squares)
  44. 移动零 (Move Zeroes)
  45. 二叉树的序列化与反序列化 (Serialize and Deserialize Binary Tree)
  46. 字符串解码 (Decode String)
  47. 分割等和子集 (Partition Equal Subset Sum)
  48. 路径总和 III (Path Sum III)
  49. 回文子串 (Palindromic Substrings)
  50. 寻找两个正序数组的中位数 (Median of Two Sorted Arrays)

详细题解

1. 两数之和 (Two Sum)

题目描述: 给定整数数组 nums 和目标值 target,在数组中找出和为目标值的两个整数,返回它们的索引。 示例: 输入:nums = [2,7,11,15], target = 9 输出:[0,1] 最优解思路: 使用哈希表存储元素值到索引的映射。遍历数组,对于每个元素 num,检查 target - num 是否在哈希表中。若存在则返回结果,否则将当前元素加入哈希表。 时间复杂度:O(n) 空间复杂度:O(n)

代码语言:javascript
复制
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        num_map = {}
        for i, num in enumerate(nums):
            complement = target - num
            if complement in num_map:
                return [num_map[complement], i]
            num_map[num] = i
        return []
代码语言:javascript
复制
class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int complement = target - nums[i];
            if (map.containsKey(complement)) {
                return new int[]{map.get(complement), i};
            }
            map.put(nums[i], i);
        }
        return new int[0];
    }
}
代码语言:javascript
复制
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> map;
        for (int i = 0; i < nums.size(); i++) {
            int complement = target - nums[i];
            if (map.find(complement) != map.end()) {
                return {map[complement], i};
            }
            map[nums[i]] = i;
        }
        return {};
    }
};
2. 反转链表 (Reverse Linked List)

题目描述: 反转一个单链表。 示例: 输入:1→2→3→4→5→NULL 输出:5→4→3→2→1→NULL 最优解思路: 使用三个指针:prev(前驱)、curr(当前)、next(后继)。遍历链表,将 curr.next 指向 prev,然后更新三个指针位置。 时间复杂度:O(n) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        prev, curr = None, head
        while curr:
            next_temp = curr.next
            curr.next = prev
            prev = curr
            curr = next_temp
        return prev
代码语言:javascript
复制
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        while (curr != null) {
            ListNode nextTemp = curr.next;
            curr.next = prev;
            prev = curr;
            curr = nextTemp;
        }
        return prev;
    }
}
代码语言:javascript
复制
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* prev = nullptr;
        ListNode* curr = head;
        while (curr) {
            ListNode* nextTemp = curr->next;
            curr->next = prev;
            prev = curr;
            curr = nextTemp;
        }
        return prev;
    }
};
3. 有效的括号 (Valid Parentheses)

题目描述: 给定只包含括号字符的字符串,判断括号是否有效。 示例: 输入:s = “()[]{}” 输出:true 最优解思路: 使用栈存储左括号。遍历字符串,遇到左括号入栈,遇到右括号则检查栈顶是否匹配。最后检查栈是否为空。 时间复杂度:O(n) 空间复杂度:O(n)

代码语言:javascript
复制
class Solution:
    def isValid(self, s: str) -> bool:
        stack = []
        mapping = {")": "(", "}": "{", "]": "["}
        for char in s:
            if char in mapping:
                top_element = stack.pop() if stack else '#'
                if mapping[char] != top_element:
                    return False
            else:
                stack.append(char)
        return not stack
代码语言:javascript
复制
class Solution {
    public boolean isValid(String s) {
        Deque<Character> stack = new ArrayDeque<>();
        Map<Character, Character> map = Map.of(')', '(', '}', '{', ']', '[');
        for (char c : s.toCharArray()) {
            if (map.containsKey(c)) {
                if (stack.isEmpty() || stack.pop() != map.get(c)) return false;
            } else {
                stack.push(c);
            }
        }
        return stack.isEmpty();
    }
}
代码语言:javascript
复制
class Solution {
public:
    bool isValid(string s) {
        stack<char> st;
        unordered_map<char, char> map = {{')', '('}, {']', '['}, {'}', '{'}};
        for (char c : s) {
            if (map.count(c)) {
                if (st.empty() || st.top() != map[c]) return false;
                st.pop();
            } else {
                st.push(c);
            }
        }
        return st.empty();
    }
};
4. 买卖股票的最佳时机 (Best Time to Buy and Sell Stock)

题目描述: 给定股票价格数组,计算一次交易的最大利润。 示例: 输入:[7,1,5,3,6,4] 输出:5(1买6卖) 最优解思路: 遍历价格数组,维护历史最低价 min_price 和最大利润 max_profit。 时间复杂度:O(n) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        min_price = float('inf')
        max_profit = 0
        for price in prices:
            min_price = min(min_price, price)
            max_profit = max(max_profit, price - min_price)
        return max_profit
代码语言:javascript
复制
class Solution {
    public int maxProfit(int[] prices) {
        int minPrice = Integer.MAX_VALUE;
        int maxProfit = 0;
        for (int price : prices) {
            minPrice = Math.min(minPrice, price);
            maxProfit = Math.max(maxProfit, price - minPrice);
        }
        return maxProfit;
    }
}
代码语言:javascript
复制
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int minPrice = INT_MAX;
        int maxProfit = 0;
        for (int price : prices) {
            minPrice = min(minPrice, price);
            maxProfit = max(maxProfit, price - minPrice);
        }
        return maxProfit;
    }
};
5. 二叉树的层序遍历 (Binary Tree Level Order Traversal)

题目描述: 返回二叉树节点值的层序遍历结果(逐层从左到右)。 示例: 输入:root = [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]] 最优解思路: 使用队列进行BFS。记录每层节点数,处理完一层后再处理下一层。 时间复杂度:O(n) 空间复杂度:O(n)

代码语言:javascript
复制
from collections import deque
class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root: return []
        result = []
        queue = deque([root])
        while queue:
            level_size = len(queue)
            current_level = []
            for _ in range(level_size):
                node = queue.popleft()
                current_level.append(node.val)
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            result.append(current_level)
        return result
代码语言:javascript
复制
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if (root == null) return result;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int levelSize = queue.size();
            List<Integer> currentLevel = new ArrayList<>();
            for (int i = 0; i < levelSize; i++) {
                TreeNode node = queue.poll();
                currentLevel.add(node.val);
                if (node.left != null) queue.offer(node.left);
                if (node.right != null) queue.offer(node.right);
            }
            result.add(currentLevel);
        }
        return result;
    }
}
代码语言:javascript
复制
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> result;
        if (!root) return result;
        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            int levelSize = q.size();
            vector<int> currentLevel;
            for (int i = 0; i < levelSize; i++) {
                TreeNode* node = q.front(); q.pop();
                currentLevel.push_back(node->val);
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }
            result.push_back(currentLevel);
        }
        return result;
    }
};
6. 最大子序和 (Maximum Subarray)

题目描述: 找出整数数组中具有最大和的连续子数组。 示例: 输入:[-2,1,-3,4,-1,2,1,-5,4] 输出:6(子数组[4,-1,2,1]) 最优解思路: Kadane算法:遍历数组,维护当前子数组和curr_sum和最大和max_sum。当curr_sum<0时重置为0。 时间复杂度:O(n) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        curr_sum = max_sum = nums[0]
        for num in nums[1:]:
            curr_sum = max(num, curr_sum + num)
            max_sum = max(max_sum, curr_sum)
        return max_sum
代码语言:javascript
复制
class Solution {
    public int maxSubArray(int[] nums) {
        int currSum = nums[0];
        int maxSum = nums[0];
        for (int i = 1; i < nums.length; i++) {
            currSum = Math.max(nums[i], currSum + nums[i]);
            maxSum = Math.max(maxSum, currSum);
        }
        return maxSum;
    }
}
代码语言:javascript
复制
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int currSum = nums[0];
        int maxSum = nums[0];
        for (int i = 1; i < nums.size(); i++) {
            currSum = max(nums[i], currSum + nums[i]);
            maxSum = max(maxSum, currSum);
        }
        return maxSum;
    }
};
7. 爬楼梯 (Climbing Stairs)

题目描述: 爬n阶楼梯,每次爬1或2阶,有多少种不同方法。 示例: 输入:3 输出:3 最优解思路: 动态规划:dp[i] = dp[i-1] + dp[i-2],使用滚动数组优化空间。 时间复杂度:O(n) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def climbStairs(self, n: int) -> int:
        if n <= 2: return n
        a, b = 1, 2
        for _ in range(3, n+1):
            a, b = b, a + b
        return b
代码语言:javascript
复制
class Solution {
    public int climbStairs(int n) {
        if (n <= 2) return n;
        int a = 1, b = 2;
        for (int i = 3; i <= n; i++) {
            int temp = a + b;
            a = b;
            b = temp;
        }
        return b;
    }
}
代码语言:javascript
复制
class Solution {
public:
    int climbStairs(int n) {
        if (n <= 2) return n;
        int a = 1, b = 2;
        for (int i = 3; i <= n; i++) {
            int temp = a + b;
            a = b;
            b = temp;
        }
        return b;
    }
};
8. 三数之和 (3Sum)

题目描述: 在数组中找到所有不重复的三元组,满足a+b+c=0。 示例: 输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]] 最优解思路: 排序+双指针:固定一个数,在剩余数组中使用双指针寻找两数之和。注意去重处理。 时间复杂度:O(n²) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        result = []
        n = len(nums)
        for i in range(n-2):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            left, right = i+1, n-1
            while left < right:
                total = nums[i] + nums[left] + nums[right]
                if total < 0:
                    left += 1
                elif total > 0:
                    right -= 1
                else:
                    result.append([nums[i], nums[left], nums[right]])
                    while left < right and nums[left] == nums[left+1]:
                        left += 1
                    while left < right and nums[right] == nums[right-1]:
                        right -= 1
                    left += 1
                    right -= 1
        return result
代码语言:javascript
复制
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> result = new ArrayList<>();
        int n = nums.length;
        for (int i = 0; i < n-2; i++) {
            if (i > 0 && nums[i] == nums[i-1]) continue;
            int left = i+1, right = n-1;
            while (left < right) {
                int sum = nums[i] + nums[left] + nums[right];
                if (sum < 0) left++;
                else if (sum > 0) right--;
                else {
                    result.add(Arrays.asList(nums[i], nums[left], nums[right]));
                    while (left < right && nums[left] == nums[left+1]) left++;
                    while (left < right && nums[right] == nums[right-1]) right--;
                    left++; right--;
                }
            }
        }
        return result;
    }
}
代码语言:javascript
复制
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> result;
        int n = nums.size();
        for (int i = 0; i < n-2; i++) {
            if (i > 0 && nums[i] == nums[i-1]) continue;
            int left = i+1, right = n-1;
            while (left < right) {
                int sum = nums[i] + nums[left] + nums[right];
                if (sum < 0) left++;
                else if (sum > 0) right--;
                else {
                    result.push_back({nums[i], nums[left], nums[right]});
                    while (left < right && nums[left] == nums[left+1]) left++;
                    while (left < right && nums[right] == nums[right-1]) right--;
                    left++; right--;
                }
            }
        }
        return result;
    }
};
9. 合并两个有序链表 (Merge Two Sorted Lists)

题目描述: 将两个升序链表合并为一个新的升序链表。 示例: 输入:1→2→4, 1→3→4 输出:1→1→2→3→4→4 最优解思路: 使用虚拟头节点,比较两个链表节点值,将较小节点连接到新链表。 时间复杂度:O(n+m) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        dummy = ListNode()
        curr = dummy
        while l1 and 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 if l1 else l2
        return dummy.next
代码语言:javascript
复制
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode();
        ListNode curr = dummy;
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                curr.next = l1;
                l1 = l1.next;
            } else {
                curr.next = l2;
                l2 = l2.next;
            }
            curr = curr.next;
        }
        curr.next = l1 != null ? l1 : l2;
        return dummy.next;
    }
}
代码语言:javascript
复制
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode dummy;
        ListNode* 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 ? l1 : l2;
        return dummy.next;
    }
};
10. 二叉树的最近公共祖先 (Lowest Common Ancestor of a Binary Tree)

题目描述: 给定二叉树和两个节点,找到这两个节点的最近公共祖先。 示例: 输入:root = [3,5,1,6,2,0,8,null,null,7,4], p=5, q=1 输出:3 最优解思路: 递归遍历二叉树:若当前节点为p或q,返回当前节点;递归左右子树;根据左右子树返回结果判断LCA位置。 时间复杂度:O(n) 空间复杂度:O(h)

代码语言:javascript
复制
class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if not root or root == p or root == q:
            return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        if left and right:
            return root
        return left or right
代码语言:javascript
复制
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) return root;
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if (left != null && right != null) return root;
        return left != null ? left : right;
    }
}
代码语言:javascript
复制
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (!root || root == p || root == q) return root;
        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        TreeNode* right = lowestCommonAncestor(root->right, p, q);
        if (left && right) return root;
        return left ? left : right;
    }
};
21. 数组中的第K个最大元素 (Kth Largest Element in an Array)

题目描述: 在未排序数组中找到第K个最大元素。 示例: 输入:[3,2,1,5,6,4], k=2 输出:5 最优解思路: 快速选择算法(基于快速排序的划分思想)。每次划分后根据pivot位置调整搜索范围。 时间复杂度:平均O(n),最坏O(n²) 空间复杂度:O(1)

代码语言:javascript
复制
import random
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        def partition(left, right):
            pivot_idx = random.randint(left, right)
            nums[pivot_idx], nums[right] = nums[right], nums[pivot_idx]
            pivot = nums[right]
            i = left
            for j in range(left, right):
                if nums[j] > pivot:  # 找第K大所以用>
                    nums[i], nums[j] = nums[j], nums[i]
                    i += 1
            nums[i], nums[right] = nums[right], nums[i]
            return i

        left, right = 0, len(nums)-1
        k = k - 1  # 转换为0-based索引
        while left <= right:
            pos = partition(left, right)
            if pos == k:
                return nums[pos]
            elif pos < k:
                left = pos + 1
            else:
                right = pos - 1
        return nums[left]
代码语言:javascript
复制
import java.util.Random;
class Solution {
    public int findKthLargest(int[] nums, int k) {
        return quickSelect(nums, 0, nums.length-1, nums.length-k);
    }
    
    private int quickSelect(int[] nums, int left, int right, int k) {
        if (left == right) return nums[left];
        Random rand = new Random();
        int pivotIdx = left + rand.nextInt(right - left);
        pivotIdx = partition(nums, left, right, pivotIdx);
        if (k == pivotIdx) return nums[k];
        else if (k < pivotIdx) return quickSelect(nums, left, pivotIdx-1, k);
        else return quickSelect(nums, pivotIdx+1, right, k);
    }
    
    private int partition(int[] nums, int left, int right, int pivotIdx) {
        int pivot = nums[pivotIdx];
        swap(nums, pivotIdx, right);
        int storeIdx = left;
        for (int i = left; i <= right; i++) {
            if (nums[i] < pivot) {
                swap(nums, storeIdx, i);
                storeIdx++;
            }
        }
        swap(nums, storeIdx, right);
        return storeIdx;
    }
    
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}
代码语言:javascript
复制
#include <vector>
#include <cstdlib>
using namespace std;

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        int left = 0, right = nums.size()-1;
        k = nums.size() - k;  // 转换为第k小
        while (left <= right) {
            int pivotIdx = partition(nums, left, right);
            if (pivotIdx == k) return nums[pivotIdx];
            else if (pivotIdx < k) left = pivotIdx + 1;
            else right = pivotIdx - 1;
        }
        return nums[left];
    }
    
private:
    int partition(vector<int>& nums, int left, int right) {
        int pivot = nums[right];
        int i = left;
        for (int j = left; j < right; j++) {
            if (nums[j] < pivot) {
                swap(nums[i], nums[j]);
                i++;
            }
        }
        swap(nums[i], nums[right]);
        return i;
    }
};
22. 除自身以外数组的乘积 (Product of Array Except Self)

题目描述: 给定整数数组,返回数组output,其中output[i]等于除nums[i]外其余元素的乘积。 示例: 输入:[1,2,3,4] 输出:[24,12,8,6] 最优解思路: 使用左右乘积列表。先从左到右计算左侧乘积,再从右到左计算右侧乘积并合并结果。 时间复杂度:O(n) 空间复杂度:O(1)(输出数组不计入空间复杂度)

代码语言:javascript
复制
class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        n = len(nums)
        result = [1] * n
        # 计算左侧乘积
        left_product = 1
        for i in range(n):
            result[i] = left_product
            left_product *= nums[i]
        # 计算右侧乘积并合并
        right_product = 1
        for i in range(n-1, -1, -1):
            result[i] *= right_product
            right_product *= nums[i]
        return result
代码语言:javascript
复制
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] result = new int[n];
        // 计算左侧乘积
        int left = 1;
        for (int i = 0; i < n; i++) {
            result[i] = left;
            left *= nums[i];
        }
        // 计算右侧乘积并合并
        int right = 1;
        for (int i = n-1; i >= 0; i--) {
            result[i] *= right;
            right *= nums[i];
        }
        return result;
    }
}
代码语言:javascript
复制
class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int n = nums.size();
        vector<int> result(n, 1);
        // 计算左侧乘积
        int left = 1;
        for (int i = 0; i < n; i++) {
            result[i] = left;
            left *= nums[i];
        }
        // 计算右侧乘积并合并
        int right = 1;
        for (int i = n-1; i >= 0; i--) {
            result[i] *= right;
            right *= nums[i];
        }
        return result;
    }
};
23. 滑动窗口最大值 (Sliding Window Maximum)

题目描述: 给定数组和滑动窗口大小k,返回每次窗口滑动时的最大值数组。 示例: 输入:nums = [1,3,-1,-3,5,3,6,7], k=3 输出:[3,3,5,5,6,7] 最优解思路: 使用双端队列维护窗口内元素的索引,保证队列头部始终为当前窗口最大值。 时间复杂度:O(n) 空间复杂度:O(k)

代码语言:javascript
复制
from collections import deque
class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        dq = deque()
        result = []
        for i in range(len(nums)):
            # 移除超出窗口的元素
            if dq and dq[0] == i - k:
                dq.popleft()
            # 移除小于当前元素的元素
            while dq and nums[dq[-1]] < nums[i]:
                dq.pop()
            dq.append(i)
            # 当窗口形成时添加结果
            if i >= k - 1:
                result.append(nums[dq[0]])
        return result
代码语言:javascript
复制
import java.util.*;
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if (nums == null || k <= 0) return new int[0];
        int n = nums.length;
        int[] result = new int[n - k + 1];
        Deque<Integer> dq = new ArrayDeque<>();
        int ri = 0;
        for (int i = 0; i < n; i++) {
            // 移除超出窗口的元素
            if (!dq.isEmpty() && dq.peekFirst() == i - k) {
                dq.pollFirst();
            }
            // 移除小于当前元素的元素
            while (!dq.isEmpty() && nums[dq.peekLast()] < nums[i]) {
                dq.pollLast();
            }
            dq.offerLast(i);
            // 当窗口形成时添加结果
            if (i >= k - 1) {
                result[ri++] = nums[dq.peekFirst()];
            }
        }
        return result;
    }
}
代码语言:javascript
复制
#include <vector>
#include <deque>
using namespace std;

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        deque<int> dq;
        vector<int> result;
        for (int i = 0; i < nums.size(); i++) {
            // 移除超出窗口的元素
            if (!dq.empty() && dq.front() == i - k) {
                dq.pop_front();
            }
            // 移除小于当前元素的元素
            while (!dq.empty() && nums[dq.back()] < nums[i]) {
                dq.pop_back();
            }
            dq.push_back(i);
            // 当窗口形成时添加结果
            if (i >= k - 1) {
                result.push_back(nums[dq.front()]);
            }
        }
        return result;
    }
};
24. 寻找重复数 (Find the Duplicate Number)

题目描述: 给定包含n+1个整数的数组,所有整数在[1,n]范围内,只有一个重复数,找出它。 示例: 输入:[1,3,4,2,2] 输出:2 最优解思路: Floyd判圈算法(快慢指针)。将数组视为链表,重复元素会导致环。 时间复杂度:O(n) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def findDuplicate(self, nums: List[int]) -> int:
        # 快慢指针
        slow = fast = nums[0]
        while True:
            slow = nums[slow]
            fast = nums[nums[fast]]
            if slow == fast:
                break
        # 寻找环入口
        slow = nums[0]
        while slow != fast:
            slow = nums[slow]
            fast = nums[fast]
        return slow
代码语言:javascript
复制
class Solution {
    public int findDuplicate(int[] nums) {
        int slow = nums[0];
        int fast = nums[0];
        do {
            slow = nums[slow];
            fast = nums[nums[fast]];
        } while (slow != fast);
        
        slow = nums[0];
        while (slow != fast) {
            slow = nums[slow];
            fast = nums[fast];
        }
        return slow;
    }
}
代码语言:javascript
复制
class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int slow = nums[0];
        int fast = nums[0];
        do {
            slow = nums[slow];
            fast = nums[nums[fast]];
        } while (slow != fast);
        
        slow = nums[0];
        while (slow != fast) {
            slow = nums[slow];
            fast = nums[fast];
        }
        return slow;
    }
};
25. LRU缓存机制 (LRU Cache)

题目描述: 设计并实现LRU(最近最少使用)缓存。 最优解思路: 哈希表+双向链表。哈希表存储键到节点的映射,双向链表维护使用顺序。 时间复杂度:O(1) 空间复杂度:O(capacity)

代码语言:javascript
复制
class DLinkedNode:
    def __init__(self, key=0, value=0):
        self.key = key
        self.value = value
        self.prev = None
        self.next = None

class LRUCache:
    def __init__(self, capacity: int):
        self.cache = {}
        self.capacity = capacity
        self.head = DLinkedNode()
        self.tail = DLinkedNode()
        self.head.next = self.tail
        self.tail.prev = self.head

    def get(self, key: int) -> int:
        if key not in self.cache:
            return -1
        node = self.cache[key]
        self.move_to_head(node)
        return node.value

    def put(self, key: int, value: int) -> None:
        if key in self.cache:
            node = self.cache[key]
            node.value = value
            self.move_to_head(node)
        else:
            node = DLinkedNode(key, value)
            self.cache[key] = node
            self.add_to_head(node)
            if len(self.cache) > self.capacity:
                removed = self.remove_tail()
                del self.cache[removed.key]

    def add_to_head(self, node):
        node.prev = self.head
        node.next = self.head.next
        self.head.next.prev = node
        self.head.next = node

    def remove_node(self, node):
        node.prev.next = node.next
        node.next.prev = node.prev

    def move_to_head(self, node):
        self.remove_node(node)
        self.add_to_head(node)

    def remove_tail(self):
        node = self.tail.prev
        self.remove_node(node)
        return node
代码语言:javascript
复制
import java.util.*;
class LRUCache {
    class DLinkedNode {
        int key;
        int value;
        DLinkedNode prev;
        DLinkedNode next;
    }

    private void addNode(DLinkedNode node) {
        node.prev = head;
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
    }

    private void removeNode(DLinkedNode node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    private void moveToHead(DLinkedNode node) {
        removeNode(node);
        addNode(node);
    }

    private DLinkedNode popTail() {
        DLinkedNode res = tail.prev;
        removeNode(res);
        return res;
    }

    private Map<Integer, DLinkedNode> cache = new HashMap<>();
    private int capacity;
    private DLinkedNode head, tail;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        head = new DLinkedNode();
        tail = new DLinkedNode();
        head.next = tail;
        tail.prev = head;
    }

    public int get(int key) {
        DLinkedNode node = cache.get(key);
        if (node == null) return -1;
        moveToHead(node);
        return node.value;
    }

    public void put(int key, int value) {
        DLinkedNode node = cache.get(key);
        if (node == null) {
            DLinkedNode newNode = new DLinkedNode();
            newNode.key = key;
            newNode.value = value;
            cache.put(key, newNode);
            addNode(newNode);
            if (cache.size() > capacity) {
                DLinkedNode tail = popTail();
                cache.remove(tail.key);
            }
        } else {
            node.value = value;
            moveToHead(node);
        }
    }
}
代码语言:javascript
复制
#include <unordered_map>
using namespace std;

class LRUCache {
private:
    struct DLinkedNode {
        int key, value;
        DLinkedNode* prev;
        DLinkedNode* next;
        DLinkedNode(): key(0), value(0), prev(nullptr), next(nullptr) {}
        DLinkedNode(int k, int v): key(k), value(v), prev(nullptr), next(nullptr) {}
    };

    void addToHead(DLinkedNode* node) {
        node->prev = head;
        node->next = head->next;
        head->next->prev = node;
        head->next = node;
    }

    void removeNode(DLinkedNode* node) {
        node->prev->next = node->next;
        node->next->prev = node->prev;
    }

    void moveToHead(DLinkedNode* node) {
        removeNode(node);
        addToHead(node);
    }

    DLinkedNode* removeTail() {
        DLinkedNode* node = tail->prev;
        removeNode(node);
        return node;
    }

    unordered_map<int, DLinkedNode*> cache;
    int capacity;
    DLinkedNode* head;
    DLinkedNode* tail;

public:
    LRUCache(int capacity) {
        this->capacity = capacity;
        head = new DLinkedNode();
        tail = new DLinkedNode();
        head->next = tail;
        tail->prev = head;
    }

    int get(int key) {
        if (!cache.count(key)) return -1;
        DLinkedNode* node = cache[key];
        moveToHead(node);
        return node->value;
    }

    void put(int key, int value) {
        if (!cache.count(key)) {
            DLinkedNode* node = new DLinkedNode(key, value);
            cache[key] = node;
            addToHead(node);
            if (cache.size() > capacity) {
                DLinkedNode* removed = removeTail();
                cache.erase(removed->key);
                delete removed;
            }
        } else {
            DLinkedNode* node = cache[key];
            node->value = value;
            moveToHead(node);
        }
    }
};
26. 盛最多水的容器 (Container With Most Water)

题目描述: 给定n个非负整数表示垂直线高度,找出两条线与x轴共同构成的容器可以容纳最多的水。 示例: 输入:[1,8,6,2,5,4,8,3,7] 输出:49 最优解思路: 双指针法:左右指针分别指向数组两端,每次移动较小高度的指针,计算并更新最大面积。 时间复杂度:O(n) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def maxArea(self, height: List[int]) -> int:
        left, right = 0, len(height)-1
        max_area = 0
        while left < right:
            area = min(height[left], height[right]) * (right - left)
            max_area = max(max_area, area)
            if height[left] < height[right]:
                left += 1
            else:
                right -= 1
        return max_area
代码语言:javascript
复制
class Solution {
    public int maxArea(int[] height) {
        int left = 0, right = height.length - 1;
        int maxArea = 0;
        while (left < right) {
            int h = Math.min(height[left], height[right]);
            int area = h * (right - left);
            maxArea = Math.max(maxArea, area);
            if (height[left] < height[right]) left++;
            else right--;
        }
        return maxArea;
    }
}
代码语言:javascript
复制
class Solution {
public:
    int maxArea(vector<int>& height) {
        int left = 0, right = height.size()-1;
        int maxArea = 0;
        while (left < right) {
            int h = min(height[left], height[right]);
            maxArea = max(maxArea, h * (right - left));
            if (height[left] < height[right]) left++;
            else right--;
        }
        return maxArea;
    }
};
27. 合并区间 (Merge Intervals)

题目描述: 给定区间集合,合并所有重叠的区间。 示例: 输入:intervals = [[1,3],[2,6],[8,10],[15,18]] 输出:[[1,6],[8,10],[15,18]] 最优解思路: 先按区间起点排序,然后遍历区间,合并重叠区间。 时间复杂度:O(n log n) 空间复杂度:O(1)(不考虑输出空间)

代码语言:javascript
复制
class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        if not intervals: return []
        intervals.sort(key=lambda x: x[0])
        merged = []
        for interval in intervals:
            if not merged or merged[-1][1] < interval[0]:
                merged.append(interval)
            else:
                merged[-1][1] = max(merged[-1][1], interval[1])
        return merged
代码语言:javascript
复制
class Solution {
    public int[][] merge(int[][] intervals) {
        if (intervals.length == 0) return new int[0][];
        Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
        LinkedList<int[]> merged = new LinkedList<>();
        for (int[] interval : intervals) {
            if (merged.isEmpty() || merged.getLast()[1] < interval[0]) {
                merged.add(interval);
            } else {
                merged.getLast()[1] = Math.max(merged.getLast()[1], interval[1]);
            }
        }
        return merged.toArray(new int[merged.size()][]);
    }
}
代码语言:javascript
复制
class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        if (intervals.empty()) return {};
        sort(intervals.begin(), intervals.end());
        vector<vector<int>> merged;
        for (auto& interval : intervals) {
            if (merged.empty() || merged.back()[1] < interval[0]) {
                merged.push_back(interval);
            } else {
                merged.back()[1] = max(merged.back()[1], interval[1]);
            }
        }
        return merged;
    }
};
28. 最长无重复子串 (Longest Substring Without Repeating Characters)

题目描述: 给定字符串,找出不包含重复字符的最长子串长度。 示例: 输入:“abcabcbb” 输出:3(“abc”) 最优解思路: 滑动窗口+哈希表记录字符最后出现位置。 时间复杂度:O(n) 空间复杂度:O(min(m, n)) 字符集大小

代码语言:javascript
复制
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        char_map = {}
        max_len = 0
        left = 0
        for right, char in enumerate(s):
            if char in char_map and char_map[char] >= left:
                left = char_map[char] + 1
            char_map[char] = right
            max_len = max(max_len, right - left + 1)
        return max_len
代码语言:javascript
复制
class Solution {
    public int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> map = new HashMap<>();
        int maxLen = 0;
        int left = 0;
        for (int right = 0; right < s.length(); right++) {
            char c = s.charAt(right);
            if (map.containsKey(c) && map.get(c) >= left) {
                left = map.get(c) + 1;
            }
            map.put(c, right);
            maxLen = Math.max(maxLen, right - left + 1);
        }
        return maxLen;
    }
}
代码语言:javascript
复制
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char, int> charMap;
        int maxLen = 0;
        int left = 0;
        for (int right = 0; right < s.size(); right++) {
            char c = s[right];
            if (charMap.find(c) != charMap.end() && charMap[c] >= left) {
                left = charMap[c] + 1;
            }
            charMap[c] = right;
            maxLen = max(maxLen, right - left + 1);
        }
        return maxLen;
    }
};
29. 最长回文子串 (Longest Palindromic Substring)

题目描述: 给定字符串,找到最长回文子串。 示例: 输入:“babad” 输出:“bab"或"aba” 最优解思路: 中心扩展法:遍历每个字符作为中心,向两边扩展寻找回文串(分奇偶情况)。 时间复杂度:O(n²) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def longestPalindrome(self, s: str) -> str:
        def expand(left, right):
            while left >= 0 and right < len(s) and s[left] == s[right]:
                left -= 1
                right += 1
            return s[left+1:right]
        
        result = ""
        for i in range(len(s)):
            # 奇数长度
            odd = expand(i, i)
            # 偶数长度
            even = expand(i, i+1)
            if len(odd) > len(result):
                result = odd
            if len(even) > len(result):
                result = even
        return result
代码语言:javascript
复制
class Solution {
    public String longestPalindrome(String s) {
        if (s == null || s.length() < 1) return "";
        int start = 0, end = 0;
        for (int i = 0; i < s.length(); i++) {
            int len1 = expand(s, i, i);
            int len2 = expand(s, i, i+1);
            int len = Math.max(len1, len2);
            if (len > end - start) {
                start = i - (len - 1) / 2;
                end = i + len / 2;
            }
        }
        return s.substring(start, end + 1);
    }
    
    private int expand(String s, int left, int right) {
        while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            left--;
            right++;
        }
        return right - left - 1;
    }
}
代码语言:javascript
复制
class Solution {
public:
    string longestPalindrome(string s) {
        if (s.empty()) return "";
        int start = 0, maxLen = 0;
        for (int i = 0; i < s.size(); i++) {
            int len1 = expand(s, i, i);
            int len2 = expand(s, i, i+1);
            int len = max(len1, len2);
            if (len > maxLen) {
                start = i - (len - 1) / 2;
                maxLen = len;
            }
        }
        return s.substr(start, maxLen);
    }
    
    int expand(string s, int left, int right) {
        while (left >= 0 && right < s.size() && s[left] == s[right]) {
            left--;
            right++;
        }
        return right - left - 1;
    }
};
30. 前K个高频元素 (Top K Frequent Elements)

题目描述: 给定整数数组和k,返回出现频率前k高的元素。 示例: 输入:nums = [1,1,1,2,2,3], k=2 输出:[1,2] 最优解思路: 哈希表统计频率,最小堆(优先队列)维护前K个高频元素。 时间复杂度:O(n log k) 空间复杂度:O(n)

代码语言:javascript
复制
import heapq
from collections import Counter
class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        count = Counter(nums)
        return heapq.nlargest(k, count.keys(), key=count.get)
代码语言:javascript
复制
class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> count = new HashMap<>();
        for (int num : nums) {
            count.put(num, count.getOrDefault(num, 0) + 1);
        }
        
        PriorityQueue<Integer> heap = new PriorityQueue<>(
            (a, b) -> count.get(a) - count.get(b)
        );
        
        for (int num : count.keySet()) {
            heap.add(num);
            if (heap.size() > k) heap.poll();
        }
        
        int[] result = new int[k];
        for (int i = 0; i < k; i++) {
            result[i] = heap.poll();
        }
        return result;
    }
}
代码语言:javascript
复制
#include <vector>
#include <unordered_map>
#include <queue>
using namespace std;

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int, int> count;
        for (int num : nums) count[num]++;
        
        auto cmp = [&](int a, int b) { return count[a] > count[b]; };
        priority_queue<int, vector<int>, decltype(cmp)> heap(cmp);
        
        for (auto& pair : count) {
            heap.push(pair.first);
            if (heap.size() > k) heap.pop();
        }
        
        vector<int> result(k);
        for (int i = k-1; i >= 0; i--) {
            result[i] = heap.top();
            heap.pop();
        }
        return result;
    }
};
31. 编辑距离 (Edit Distance)

题目描述: 给定两个单词,计算将word1转换为word2所需的最少操作数(插入、删除、替换)。 示例: 输入:word1=“horse”, word2=“ros” 输出:3 最优解思路: 动态规划:dp[i][j]表示word1前i个字符到word2前j个字符的编辑距离。 时间复杂度:O(mn) 空间复杂度:O(mn)

代码语言:javascript
复制
class Solution:
    def minDistance(self, word1: str, word2: str) -> int:
        m, n = len(word1), len(word2)
        dp = [[0]*(n+1) for _ in range(m+1)]
        # 初始化
        for i in range(m+1): dp[i][0] = i
        for j in range(n+1): dp[0][j] = j
        
        for i in range(1, m+1):
            for j in range(1, n+1):
                if word1[i-1] == word2[j-1]:
                    dp[i][j] = dp[i-1][j-1]
                else:
                    dp[i][j] = 1 + min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])
        return dp[m][n]
代码语言:javascript
复制
class Solution {
    public int minDistance(String word1, String word2) {
        int m = word1.length(), n = word2.length();
        int[][] dp = new int[m+1][n+1];
        for (int i = 0; i <= m; i++) dp[i][0] = i;
        for (int j = 0; j <= n; j++) dp[0][j] = j;
        
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (word1.charAt(i-1) == word2.charAt(j-1)) {
                    dp[i][j] = dp[i-1][j-1];
                } else {
                    dp[i][j] = 1 + Math.min(dp[i-1][j], 
                                       Math.min(dp[i][j-1], dp[i-1][j-1]));
                }
            }
        }
        return dp[m][n];
    }
}
代码语言:javascript
复制
class Solution {
public:
    int minDistance(string word1, string word2) {
        int m = word1.size(), n = word2.size();
        vector<vector<int>> dp(m+1, vector<int>(n+1, 0));
        for (int i = 0; i <= m; i++) dp[i][0] = i;
        for (int j = 0; j <= n; j++) dp[0][j] = j;
        
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (word1[i-1] == word2[j-1]) {
                    dp[i][j] = dp[i-1][j-1];
                } else {
                    dp[i][j] = 1 + min({dp[i-1][j], dp[i][j-1], dp[i-1][j-1]});
                }
            }
        }
        return dp[m][n];
    }
};
32. 最大矩形 (Maximal Rectangle)

题目描述: 给定二进制矩阵,找出只包含’1’的最大矩形面积。 示例: 输入: [ [“1”,“0”,“1”,“0”,“0”], [“1”,“0”,“1”,“1”,“1”], [“1”,“1”,“1”,“1”,“1”], [“1”,“0”,“0”,“1”,“0”] ] 输出:6 最优解思路: 按行遍历,计算每列的高度,转化为柱状图最大矩形问题(使用单调栈)。 时间复杂度:O(mn) 空间复杂度:O(n)

代码语言:javascript
复制
class Solution:
    def maximalRectangle(self, matrix: List[List[str]]) -> int:
        if not matrix: return 0
        m, n = len(matrix), len(matrix[0])
        heights = [0] * n
        max_area = 0
        
        for i in range(m):
            for j in range(n):
                heights[j] = heights[j] + 1 if matrix[i][j] == "1" else 0
            max_area = max(max_area, self.largestRectangleArea(heights))
        return max_area
    
    def largestRectangleArea(self, heights: List[int]) -> int:
        stack = [-1]
        max_area = 0
        for i in range(len(heights)):
            while stack[-1] != -1 and heights[stack[-1]] >= heights[i]:
                h = heights[stack.pop()]
                w = i - stack[-1] - 1
                max_area = max(max_area, h * w)
            stack.append(i)
        
        while stack[-1] != -1:
            h = heights[stack.pop()]
            w = len(heights) - stack[-1] - 1
            max_area = max(max_area, h * w)
        return max_area
代码语言:javascript
复制
class Solution {
    public int maximalRectangle(char[][] matrix) {
        if (matrix == null || matrix.length == 0) return 0;
        int m = matrix.length, n = matrix[0].length;
        int[] heights = new int[n];
        int maxArea = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                heights[j] = matrix[i][j] == '1' ? heights[j] + 1 : 0;
            }
            maxArea = Math.max(maxArea, largestRectangleArea(heights));
        }
        return maxArea;
    }
    
    private int largestRectangleArea(int[] heights) {
        Stack<Integer> stack = new Stack<>();
        stack.push(-1);
        int maxArea = 0;
        for (int i = 0; i < heights.length; i++) {
            while (stack.peek() != -1 && heights[stack.peek()] >= heights[i]) {
                int h = heights[stack.pop()];
                int w = i - stack.peek() - 1;
                maxArea = Math.max(maxArea, h * w);
            }
            stack.push(i);
        }
        while (stack.peek() != -1) {
            int h = heights[stack.pop()];
            int w = heights.length - stack.peek() - 1;
            maxArea = Math.max(maxArea, h * w);
        }
        return maxArea;
    }
}
代码语言:javascript
复制
class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        if (matrix.empty()) return 0;
        int m = matrix.size(), n = matrix[0].size();
        vector<int> heights(n, 0);
        int maxArea = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                heights[j] = matrix[i][j] == '1' ? heights[j] + 1 : 0;
            }
            maxArea = max(maxArea, largestRectangleArea(heights));
        }
        return maxArea;
    }
    
    int largestRectangleArea(vector<int>& heights) {
        stack<int> st;
        st.push(-1);
        int maxArea = 0;
        for (int i = 0; i < heights.size(); i++) {
            while (st.top() != -1 && heights[st.top()] >= heights[i]) {
                int h = heights[st.top()]; st.pop();
                int w = i - st.top() - 1;
                maxArea = max(maxArea, h * w);
            }
            st.push(i);
        }
        while (st.top() != -1) {
            int h = heights[st.top()]; st.pop();
            int w = heights.size() - st.top() - 1;
            maxArea = max(maxArea, h * w);
        }
        return maxArea;
    }
};
33. 二叉树中的最大路径和 (Binary Tree Maximum Path Sum)

题目描述: 给定二叉树,找出路径和最大的路径(路径是树中任意节点间的序列)。 示例: 输入:[-10,9,20,null,null,15,7] 输出:42(15→20→7) 最优解思路: 递归计算每个节点的贡献值(以该节点为起点的最大路径和),同时更新全局最大路径和。 时间复杂度:O(n) 空间复杂度:O(h)

代码语言:javascript
复制
class Solution:
    def maxPathSum(self, root: TreeNode) -> int:
        self.max_sum = float('-inf')
        def max_gain(node):
            if not node: return 0
            left_gain = max(max_gain(node.left), 0)
            right_gain = max(max_gain(node.right), 0)
            # 当前节点为根的路径和
            price_newpath = node.val + left_gain + right_gain
            self.max_sum = max(self.max_sum, price_newpath)
            # 返回当前节点的最大贡献值
            return node.val + max(left_gain, right_gain)
        
        max_gain(root)
        return self.max_sum
代码语言:javascript
复制
class Solution {
    int maxSum = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        maxGain(root);
        return maxSum;
    }
    
    private int maxGain(TreeNode node) {
        if (node == null) return 0;
        int leftGain = Math.max(maxGain(node.left), 0);
        int rightGain = Math.max(maxGain(node.right), 0);
        int priceNewpath = node.val + leftGain + rightGain;
        maxSum = Math.max(maxSum, priceNewpath);
        return node.val + Math.max(leftGain, rightGain);
    }
}
代码语言:javascript
复制
class Solution {
public:
    int maxPathSum(TreeNode* root) {
        int maxSum = INT_MIN;
        maxGain(root, maxSum);
        return maxSum;
    }
    
    int maxGain(TreeNode* node, int& maxSum) {
        if (!node) return 0;
        int leftGain = max(maxGain(node->left, maxSum), 0);
        int rightGain = max(maxGain(node->right, maxSum), 0);
        int priceNewpath = node->val + leftGain + rightGain;
        maxSum = max(maxSum, priceNewpath);
        return node->val + max(leftGain, rightGain);
    }
};
34. 实现 Trie (前缀树) (Implement Trie (Prefix Tree))

题目描述: 实现Trie数据结构:insert, search, startsWith。 最优解思路: 使用嵌套字典实现,每个节点包含子节点映射和单词结束标志。 时间复杂度:O(L)(L为单词长度) 空间复杂度:O(N*L)(N为插入单词数)

代码语言:javascript
复制
class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_end = False

class Trie:
    def __init__(self):
        self.root = TrieNode()
    
    def insert(self, word: str) -> None:
        node = self.root
        for char in word:
            if char not in node.children:
                node.children[char] = TrieNode()
            node = node.children[char]
        node.is_end = True
    
    def search(self, word: str) -> bool:
        node = self.root
        for char in word:
            if char not in node.children:
                return False
            node = node.children[char]
        return node.is_end
    
    def startsWith(self, prefix: str) -> bool:
        node = self.root
        for char in prefix:
            if char not in node.children:
                return False
            node = node.children[char]
        return True
代码语言:javascript
复制
class TrieNode {
    public Map<Character, TrieNode> children;
    public boolean isEnd;
    public TrieNode() {
        children = new HashMap<>();
        isEnd = false;
    }
}

class Trie {
    private TrieNode root;
    public Trie() {
        root = new TrieNode();
    }
    
    public void insert(String word) {
        TrieNode node = root;
        for (char c : word.toCharArray()) {
            node.children.putIfAbsent(c, new TrieNode());
            node = node.children.get(c);
        }
        node.isEnd = true;
    }
    
    public boolean search(String word) {
        TrieNode node = root;
        for (char c : word.toCharArray()) {
            if (!node.children.containsKey(c)) return false;
            node = node.children.get(c);
        }
        return node.isEnd;
    }
    
    public boolean startsWith(String prefix) {
        TrieNode node = root;
        for (char c : prefix.toCharArray()) {
            if (!node.children.containsKey(c)) return false;
            node = node.children.get(c);
        }
        return true;
    }
}
代码语言:javascript
复制
class TrieNode {
public:
    unordered_map<char, TrieNode*> children;
    bool isEnd;
    TrieNode() : isEnd(false) {}
};

class Trie {
private:
    TrieNode* root;
public:
    Trie() {
        root = new TrieNode();
    }
    
    void insert(string word) {
        TrieNode* node = root;
        for (char c : word) {
            if (!node->children.count(c)) {
                node->children[c] = new TrieNode();
            }
            node = node->children[c];
        }
        node->isEnd = true;
    }
    
    bool search(string word) {
        TrieNode* node = root;
        for (char c : word) {
            if (!node->children.count(c)) return false;
            node = node->children[c];
        }
        return node->isEnd;
    }
    
    bool startsWith(string prefix) {
        TrieNode* node = root;
        for (char c : prefix) {
            if (!node->children.count(c)) return false;
            node = node->children[c];
        }
        return true;
    }
};
35. 回文链表 (Palindrome Linked List)

题目描述: 判断链表是否为回文链表。 示例: 输入:1→2→2→1 输出:true 最优解思路: 快慢指针找中点,反转后半部分,比较两部分是否相同。 时间复杂度:O(n) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        if not head or not head.next: return True
        # 找中点
        slow, fast = head, head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
        # 反转后半部分
        prev, curr = None, slow
        while curr:
            next_temp = curr.next
            curr.next = prev
            prev = curr
            curr = next_temp
        # 比较两部分
        p1, p2 = head, prev
        while p2:  # 只需比较后半部分长度
            if p1.val != p2.val:
                return False
            p1 = p1.next
            p2 = p2.next
        return True
代码语言:javascript
复制
class Solution {
    public boolean isPalindrome(ListNode head) {
        if (head == null || head.next == null) return true;
        // 找中点
        ListNode slow = head, fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        // 反转后半部分
        ListNode prev = null, curr = slow;
        while (curr != null) {
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        // 比较两部分
        ListNode p1 = head, p2 = prev;
        while (p2 != null) {
            if (p1.val != p2.val) return false;
            p1 = p1.next;
            p2 = p2.next;
        }
        return true;
    }
}
代码语言:javascript
复制
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if (!head || !head->next) return true;
        // 找中点
        ListNode* slow = head;
        ListNode* fast = head;
        while (fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
        }
        // 反转后半部分
        ListNode* prev = nullptr;
        ListNode* curr = slow;
        while (curr) {
            ListNode* next = curr->next;
            curr->next = prev;
            prev = curr;
            curr = next;
        }
        // 比较两部分
        ListNode* p1 = head;
        ListNode* p2 = prev;
        while (p2) {
            if (p1->val != p2->val) return false;
            p1 = p1->next;
            p2 = p2->next;
        }
        return true;
    }
};
36. 二叉树的锯齿形层序遍历 (Binary Tree Zigzag Level Order Traversal)

题目描述: 先从左往右,再从右往左进行层序遍历。 示例: 输入:[3,9,20,null,null,15,7] 输出:[[3],[20,9],[15,7]] 最优解思路: BFS遍历,使用双端队列根据层级决定插入方向。 时间复杂度:O(n) 空间复杂度:O(n)

代码语言:javascript
复制
class Solution:
    def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root: return []
        result = []
        queue = deque([root])
        level = 0
        while queue:
            size = len(queue)
            current_level = deque()
            for _ in range(size):
                node = queue.popleft()
                if level % 2 == 0:
                    current_level.append(node.val)
                else:
                    current_level.appendleft(node.val)
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            result.append(list(current_level))
            level += 1
        return result
代码语言:javascript
复制
class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<>();
        if (root == null) return result;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        boolean leftToRight = true;
        while (!queue.isEmpty()) {
            int size = queue.size();
            LinkedList<Integer> level = new LinkedList<>();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                if (leftToRight) {
                    level.addLast(node.val);
                } else {
                    level.addFirst(node.val);
                }
                if (node.left != null) queue.offer(node.left);
                if (node.right != null) queue.offer(node.right);
            }
            result.add(level);
            leftToRight = !leftToRight;
        }
        return result;
    }
}
代码语言:javascript
复制
class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        vector<vector<int>> result;
        if (!root) return result;
        queue<TreeNode*> q;
        q.push(root);
        bool leftToRight = true;
        while (!q.empty()) {
            int size = q.size();
            vector<int> level(size);
            for (int i = 0; i < size; i++) {
                TreeNode* node = q.front(); q.pop();
                int index = leftToRight ? i : size - 1 - i;
                level[index] = node->val;
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }
            result.push_back(level);
            leftToRight = !leftToRight;
        }
        return result;
    }
};
37. 环形链表 II (Linked List Cycle II)

题目描述: 给定链表,返回环的入口节点,无环返回null。 示例: 输入:head = [3,2,0,-4], pos=1 输出:值为2的节点 最优解思路: Floyd算法:快慢指针相遇后,慢指针与从起点出发的指针再次相遇点为入口。 时间复杂度:O(n) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        slow = fast = head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                ptr = head
                while ptr != slow:
                    ptr = ptr.next
                    slow = slow.next
                return ptr
        return None
代码语言:javascript
复制
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head, fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                ListNode ptr = head;
                while (ptr != slow) {
                    ptr = ptr.next;
                    slow = slow.next;
                }
                return ptr;
            }
        }
        return null;
    }
}
代码语言:javascript
复制
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *slow = head, *fast = head;
        while (fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
            if (slow == fast) {
                ListNode *ptr = head;
                while (ptr != slow) {
                    ptr = ptr->next;
                    slow = slow->next;
                }
                return ptr;
            }
        }
        return nullptr;
    }
};
38. 合并K个升序链表 (Merge k Sorted Lists)

题目描述: 合并k个升序链表。 示例: 输入:lists = [[1,4,5],[1,3,4],[2,6]] 输出:[1,1,2,3,4,4,5,6] 最优解思路: 使用最小堆(优先队列)维护所有链表当前节点。 时间复杂度:O(N log k) 空间复杂度:O(k)

代码语言:javascript
复制
import heapq
class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        dummy = ListNode()
        curr = dummy
        heap = []
        for i, node in enumerate(lists):
            if node:
                heapq.heappush(heap, (node.val, i, node))
        while heap:
            val, idx, node = heapq.heappop(heap)
            curr.next = node
            curr = curr.next
            if node.next:
                heapq.heappush(heap, (node.next.val, idx, node.next))
        return dummy.next
代码语言:javascript
复制
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) return null;
        PriorityQueue<ListNode> heap = new PriorityQueue<>((a, b) -> a.val - b.val);
        ListNode dummy = new ListNode();
        ListNode curr = dummy;
        for (ListNode node : lists) {
            if (node != null) heap.offer(node);
        }
        while (!heap.isEmpty()) {
            ListNode node = heap.poll();
            curr.next = node;
            curr = curr.next;
            if (node.next != null) heap.offer(node.next);
        }
        return dummy.next;
    }
}
代码语言:javascript
复制
class Solution {
public:
    struct Compare {
        bool operator()(ListNode* a, ListNode* b) {
            return a->val > b->val;
        }
    };
    
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        priority_queue<ListNode*, vector<ListNode*>, Compare> heap;
        ListNode dummy;
        ListNode* curr = &dummy;
        for (ListNode* node : lists) {
            if (node) heap.push(node);
        }
        while (!heap.empty()) {
            ListNode* node = heap.top(); heap.pop();
            curr->next = node;
            curr = curr->next;
            if (node->next) heap.push(node->next);
        }
        return dummy.next;
    }
};
39. 最长上升子序列 (Longest Increasing Subsequence)

题目描述: 给定整数数组,找到最长严格递增子序列的长度。 示例: 输入:[10,9,2,5,3,7,101,18] 输出:4(子序列[2,3,7,101]) 最优解思路: 动态规划+贪心+二分查找:维护一个tails数组,tails[i]表示长度为i+1的上升子序列的最小尾部值。 时间复杂度:O(n log n) 空间复杂度:O(n)

代码语言:javascript
复制
class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        tails = []
        for num in nums:
            # 二分查找插入位置
            left, right = 0, len(tails)
            while left < right:
                mid = (left + right) // 2
                if tails[mid] < num:
                    left = mid + 1
                else:
                    right = mid
            if left == len(tails):
                tails.append(num)
            else:
                tails[left] = num
        return len(tails)
代码语言:javascript
复制
class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] tails = new int[nums.length];
        int size = 0;
        for (int num : nums) {
            int left = 0, right = size;
            while (left < right) {
                int mid = left + (right - left) / 2;
                if (tails[mid] < num) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }
            if (left == size) {
                tails[size++] = num;
            } else {
                tails[left] = num;
            }
        }
        return size;
    }
}
代码语言:javascript
复制
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> tails;
        for (int num : nums) {
            auto it = lower_bound(tails.begin(), tails.end(), num);
            if (it == tails.end()) {
                tails.push_back(num);
            } else {
                *it = num;
            }
        }
        return tails.size();
    }
};
40. 打家劫舍 (House Robber)

题目描述: 给定数组表示沿街房屋金额,不能偷相邻房屋,求最大金额。 示例: 输入:[2,7,9,3,1] 输出:12(2+9+1) 最优解思路: 动态规划:dp[i] = max(dp[i-1], dp[i-2] + nums[i]),可优化为滚动数组。 时间复杂度:O(n) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def rob(self, nums: List[int]) -> int:
        prev_max, curr_max = 0, 0
        for num in nums:
            temp = curr_max
            curr_max = max(prev_max + num, curr_max)
            prev_max = temp
        return curr_max
代码语言:javascript
复制
class Solution {
    public int rob(int[] nums) {
        int prev = 0, curr = 0;
        for (int num : nums) {
            int temp = curr;
            curr = Math.max(prev + num, curr);
            prev = temp;
        }
        return curr;
    }
}
代码语言:javascript
复制
class Solution {
public:
    int rob(vector<int>& nums) {
        int prev = 0, curr = 0;
        for (int num : nums) {
            int temp = curr;
            curr = max(prev + num, curr);
            prev = temp;
        }
        return curr;
    }
};
41. 打家劫舍 III (House Robber III)

题目描述: 二叉树结构房屋,不能偷相邻节点,求最大金额。 示例: 输入:[3,2,3,null,3,null,1] 输出:7(3+3+1) 最优解思路: 树形DP:每个节点返回[偷当前节点的最大收益, 不偷当前节点的最大收益]。 时间复杂度:O(n) 空间复杂度:O(h)

代码语言:javascript
复制
class Solution:
    def rob(self, root: TreeNode) -> int:
        def dfs(node):
            if not node: return (0, 0)
            left = dfs(node.left)
            right = dfs(node.right)
            # 偷当前节点:当前值+不偷左右子节点
            rob = node.val + left[1] + right[1]
            # 不偷当前节点:左右子节点的最大值之和
            not_rob = max(left) + max(right)
            return (rob, not_rob)
        return max(dfs(root))
代码语言:javascript
复制
class Solution {
    public int rob(TreeNode root) {
        int[] result = dfs(root);
        return Math.max(result[0], result[1]);
    }
    
    private int[] dfs(TreeNode node) {
        if (node == null) return new int[]{0, 0};
        int[] left = dfs(node.left);
        int[] right = dfs(node.right);
        int rob = node.val + left[1] + right[1];
        int notRob = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        return new int[]{rob, notRob};
    }
}
代码语言:javascript
复制
class Solution {
public:
    int rob(TreeNode* root) {
        auto result = dfs(root);
        return max(result[0], result[1]);
    }
    
    pair<int, int> dfs(TreeNode* node) {
        if (!node) return {0, 0};
        auto left = dfs(node->left);
        auto right = dfs(node->right);
        int rob = node->val + left.second + right.second;
        int notRob = max(left.first, left.second) + max(right.first, right.second);
        return {rob, notRob};
    }
};
42. 搜索二维矩阵 II (Search a 2D Matrix II)

题目描述: m x n矩阵,每行从左到右升序,每列从上到下升序,判断target是否存在。 示例: 输入: [ [1,4,7,11,15], [2,5,8,12,19], [3,6,9,16,22], [10,13,14,17,24], [18,21,23,26,30] ], target=5 输出:true 最优解思路: 从右上角开始搜索,比target大则左移,比target小则下移。 时间复杂度:O(m+n) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def searchMatrix(self, matrix, target):
        if not matrix: return False
        row, col = 0, len(matrix[0])-1
        while row < len(matrix) and col >= 0:
            if matrix[row][col] == target:
                return True
            elif matrix[row][col] > target:
                col -= 1
            else:
                row += 1
        return False
代码语言:javascript
复制
class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0) return false;
        int row = 0, col = matrix[0].length - 1;
        while (row < matrix.length && col >= 0) {
            if (matrix[row][col] == target) return true;
            else if (matrix[row][col] > target) col--;
            else row++;
        }
        return false;
    }
}
代码语言:javascript
复制
class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if (matrix.empty()) return false;
        int row = 0, col = matrix[0].size()-1;
        while (row < matrix.size() && col >= 0) {
            if (matrix[row][col] == target) return true;
            else if (matrix[row][col] > target) col--;
            else row++;
        }
        return false;
    }
};
43. 完全平方数 (Perfect Squares)

题目描述: 给定正整数n,找到若干个完全平方数(1,4,9,…)使它们的和为n,返回最少个数。 示例: 输入:n=12 输出:3(4+4+4) 最优解思路: 动态规划:dp[i]表示和为i的最小平方数个数,dp[i]=min(dp[i], dp[i-j*j]+1)。 时间复杂度:O(n√n) 空间复杂度:O(n)

代码语言:javascript
复制
class Solution:
    def numSquares(self, n: int) -> int:
        dp = [float('inf')]*(n+1)
        dp[0] = 0
        for i in range(1, n+1):
            j = 1
            while j*j <= i:
                dp[i] = min(dp[i], dp[i-j*j]+1)
                j += 1
        return dp[n]
代码语言:javascript
复制
class Solution {
    public int numSquares(int n) {
        int[] dp = new int[n+1];
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j*j <= i; j++) {
                dp[i] = Math.min(dp[i], dp[i - j*j] + 1);
            }
        }
        return dp[n];
    }
}
代码语言:javascript
复制
class Solution {
public:
    int numSquares(int n) {
        vector<int> dp(n+1, INT_MAX);
        dp[0] = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j*j <= i; j++) {
                dp[i] = min(dp[i], dp[i - j*j] + 1);
            }
        }
        return dp[n];
    }
};
44. 移动零 (Move Zeroes)

题目描述: 将数组中的0移动到末尾,保持非零元素相对顺序。 示例: 输入:[0,1,0,3,12] 输出:[1,3,12,0,0] 最优解思路: 双指针:左指针指向已处理序列尾部,右指针遍历数组,非零元素交换到左侧。 时间复杂度:O(n) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        left = 0
        for right in range(len(nums)):
            if nums[right] != 0:
                nums[left], nums[right] = nums[right], nums[left]
                left += 1
代码语言:javascript
复制
class Solution {
    public void moveZeroes(int[] nums) {
        int left = 0;
        for (int right = 0; right < nums.length; right++) {
            if (nums[right] != 0) {
                int temp = nums[left];
                nums[left] = nums[right];
                nums[right] = temp;
                left++;
            }
        }
    }
}
代码语言:javascript
复制
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int left = 0;
        for (int right = 0; right < nums.size(); right++) {
            if (nums[right] != 0) {
                swap(nums[left], nums[right]);
                left++;
            }
        }
    }
};
45. 二叉树的序列化与反序列化 (Serialize and Deserialize Binary Tree)

题目描述: 设计算法实现二叉树的序列化与反序列化。 最优解思路: 使用DFS(前序遍历)序列化,特殊符号表示空节点。 时间复杂度:O(n) 空间复杂度:O(n)

代码语言:javascript
复制
class Codec:
    def serialize(self, root):
        if not root: return "X"
        left = self.serialize(root.left)
        right = self.serialize(root.right)
        return str(root.val) + "," + left + "," + right

    def deserialize(self, data):
        nodes = data.split(",")
        return self.buildTree(iter(nodes))
    
    def buildTree(self, nodes):
        val = next(nodes)
        if val == "X": return None
        node = TreeNode(int(val))
        node.left = self.buildTree(nodes)
        node.right = self.buildTree(nodes)
        return node
代码语言:javascript
复制
public class Codec {
    public String serialize(TreeNode root) {
        if (root == null) return "X";
        String left = serialize(root.left);
        String right = serialize(root.right);
        return root.val + "," + left + "," + right;
    }

    public TreeNode deserialize(String data) {
        String[] nodes = data.split(",");
        return buildTree(new LinkedList<>(Arrays.asList(nodes)));
    }
    
    private TreeNode buildTree(Queue<String> nodes) {
        String val = nodes.poll();
        if (val.equals("X")) return null;
        TreeNode node = new TreeNode(Integer.parseInt(val));
        node.left = buildTree(nodes);
        node.right = buildTree(nodes);
        return node;
    }
}
代码语言:javascript
复制
class Codec {
public:
    string serialize(TreeNode* root) {
        if (!root) return "X";
        return to_string(root->val) + "," + serialize(root->left) + "," + serialize(root->right);
    }

    TreeNode* deserialize(string data) {
        stringstream ss(data);
        return buildTree(ss);
    }
    
    TreeNode* buildTree(stringstream& ss) {
        string val;
        getline(ss, val, ',');
        if (val == "X") return nullptr;
        TreeNode* node = new TreeNode(stoi(val));
        node->left = buildTree(ss);
        node->right = buildTree(ss);
        return node;
    }
};
46. 字符串解码 (Decode String)

题目描述: 给定编码字符串k[encoded_string],返回解码后字符串。 示例: 输入:“3[a]2[bc]” 输出:“aaabcbc” 最优解思路: 使用栈处理嵌套结构,遇到’]‘时出栈直到’[',再出栈数字。 时间复杂度:O(n) 空间复杂度:O(n)

代码语言:javascript
复制
class Solution:
    def decodeString(self, s: str) -> str:
        stack = []
        curr_num = 0
        curr_str = ""
        for char in s:
            if char == '[':
                stack.append(curr_str)
                stack.append(curr_num)
                curr_str = ""
                curr_num = 0
            elif char == ']':
                num = stack.pop()
                prev_str = stack.pop()
                curr_str = prev_str + num * curr_str
            elif char.isdigit():
                curr_num = curr_num * 10 + int(char)
            else:
                curr_str += char
        return curr_str
代码语言:javascript
复制
class Solution {
    public String decodeString(String s) {
        Stack<Integer> numStack = new Stack<>();
        Stack<String> strStack = new Stack<>();
        int currNum = 0;
        StringBuilder currStr = new StringBuilder();
        for (char c : s.toCharArray()) {
            if (Character.isDigit(c)) {
                currNum = currNum * 10 + (c - '0');
            } else if (c == '[') {
                numStack.push(currNum);
                strStack.push(currStr.toString());
                currNum = 0;
                currStr = new StringBuilder();
            } else if (c == ']') {
                int num = numStack.pop();
                StringBuilder prevStr = new StringBuilder(strStack.pop());
                for (int i = 0; i < num; i++) {
                    prevStr.append(currStr);
                }
                currStr = prevStr;
            } else {
                currStr.append(c);
            }
        }
        return currStr.toString();
    }
}
代码语言:javascript
复制
class Solution {
public:
    string decodeString(string s) {
        stack<int> numStack;
        stack<string> strStack;
        int currNum = 0;
        string currStr = "";
        for (char c : s) {
            if (isdigit(c)) {
                currNum = currNum * 10 + (c - '0');
            } else if (c == '[') {
                numStack.push(currNum);
                strStack.push(currStr);
                currNum = 0;
                currStr = "";
            } else if (c == ']') {
                int num = numStack.top(); numStack.pop();
                string prevStr = strStack.top(); strStack.pop();
                string temp;
                for (int i = 0; i < num; i++) {
                    temp += currStr;
                }
                currStr = prevStr + temp;
            } else {
                currStr += c;
            }
        }
        return currStr;
    }
};
47. 分割等和子集 (Partition Equal Subset Sum)

题目描述: 判断数组是否可分割成两个和相等的子集。 示例: 输入:[1,5,11,5] 输出:true([1,5,5]和[11]) 最优解思路: 转化为背包问题:能否用数组中元素拼出sum/2。 时间复杂度:O(n*sum) 空间复杂度:O(sum)

代码语言:javascript
复制
class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        total = sum(nums)
        if total % 2 != 0: return False
        target = total // 2
        dp = [False]*(target+1)
        dp[0] = True
        for num in nums:
            for j in range(target, num-1, -1):
                if dp[j-num]:
                    dp[j] = True
        return dp[target]
代码语言:javascript
复制
class Solution {
    public boolean canPartition(int[] nums) {
        int total = 0;
        for (int num : nums) total += num;
        if (total % 2 != 0) return false;
        int target = total / 2;
        boolean[] dp = new boolean[target+1];
        dp[0] = true;
        for (int num : nums) {
            for (int j = target; j >= num; j--) {
                if (dp[j - num]) {
                    dp[j] = true;
                }
            }
        }
        return dp[target];
    }
}
代码语言:javascript
复制
class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int total = accumulate(nums.begin(), nums.end(), 0);
        if (total % 2 != 0) return false;
        int target = total / 2;
        vector<bool> dp(target+1, false);
        dp[0] = true;
        for (int num : nums) {
            for (int j = target; j >= num; j--) {
                if (dp[j - num]) {
                    dp[j] = true;
                }
            }
        }
        return dp[target];
    }
};
48. 路径总和 III (Path Sum III)

题目描述: 找出二叉树中和等于目标值的路径数量(路径不需从根开始)。 示例: 输入:root=[10,5,-3,3,2,null,11,3,-2,null,1], sum=8 输出:3 最优解思路: 前缀和+DFS:用哈希表存储路径前缀和,回溯时更新哈希表。 时间复杂度:O(n) 空间复杂度:O(n)

代码语言:javascript
复制
class Solution:
    def pathSum(self, root: TreeNode, sum: int) -> int:
        from collections import defaultdict
        prefixSum = defaultdict(int)
        prefixSum[0] = 1  # 初始前缀和为0的路径有1条
        self.count = 0
        
        def dfs(node, curr_sum):
            if not node: return
            curr_sum += node.val
            # 查找前缀和为curr_sum - target的路径数量
            self.count += prefixSum.get(curr_sum - sum, 0)
            prefixSum[curr_sum] += 1
            dfs(node.left, curr_sum)
            dfs(node.right, curr_sum)
            prefixSum[curr_sum] -= 1  # 回溯
        
        dfs(root, 0)
        return self.count
代码语言:javascript
复制
class Solution {
    public int pathSum(TreeNode root, int sum) {
        Map<Integer, Integer> prefixSum = new HashMap<>();
        prefixSum.put(0, 1);
        int[] count = new int[1];
        dfs(root, 0, sum, prefixSum, count);
        return count[0];
    }
    
    private void dfs(TreeNode node, int currSum, int target, Map<Integer, Integer> prefixSum, int[] count) {
        if (node == null) return;
        currSum += node.val;
        count[0] += prefixSum.getOrDefault(currSum - target, 0);
        prefixSum.put(currSum, prefixSum.getOrDefault(currSum, 0) + 1);
        dfs(node.left, currSum, target, prefixSum, count);
        dfs(node.right, currSum, target, prefixSum, count);
        prefixSum.put(currSum, prefixSum.get(currSum) - 1);
    }
}
代码语言:javascript
复制
class Solution {
public:
    int pathSum(TreeNode* root, int sum) {
        unordered_map<int, int> prefixSum;
        prefixSum[0] = 1;
        int count = 0;
        dfs(root, 0, sum, prefixSum, count);
        return count;
    }
    
    void dfs(TreeNode* node, int currSum, int target, unordered_map<int, int>& prefixSum, int& count) {
        if (!node) return;
        currSum += node->val;
        count += prefixSum[currSum - target];
        prefixSum[currSum]++;
        dfs(node->left, currSum, target, prefixSum, count);
        dfs(node->right, currSum, target, prefixSum, count);
        prefixSum[currSum]--;
    }
};
49. 回文子串 (Palindromic Substrings)

题目描述: 计算字符串中回文子串的数量。 示例: 输入:“abc” 输出:3(“a”,“b”,“c”) 最优解思路: 中心扩展法:以每个字符(或字符间)为中心向两边扩展统计回文串。 时间复杂度:O(n²) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def countSubstrings(self, s: str) -> int:
        n = len(s)
        count = 0
        for center in range(2*n-1):
            left = center // 2
            right = left + center % 2
            while left >= 0 and right < n and s[left] == s[right]:
                count += 1
                left -= 1
                right += 1
        return count
代码语言:javascript
复制
class Solution {
    public int countSubstrings(String s) {
        int n = s.length();
        int count = 0;
        for (int center = 0; center < 2*n-1; center++) {
            int left = center / 2;
            int right = left + center % 2;
            while (left >= 0 && right < n && s.charAt(left) == s.charAt(right)) {
                count++;
                left--;
                right++;
            }
        }
        return count;
    }
}
代码语言:javascript
复制
class Solution {
public:
    int countSubstrings(string s) {
        int n = s.size();
        int count = 0;
        for (int center = 0; center < 2*n-1; center++) {
            int left = center / 2;
            int right = left + center % 2;
            while (left >= 0 && right < n && s[left] == s[right]) {
                count++;
                left--;
                right++;
            }
        }
        return count;
    }
};
50. 寻找两个正序数组的中位数 (Median of Two Sorted Arrays)

题目描述: 给定两个大小分别为m和n的正序数组,找出中位数。 示例: 输入:nums1=[1,3], nums2=[2] 输出:2.0 最优解思路: 二分查找:在两个数组中找到分割线,使左边元素个数等于右边(或差1)。 时间复杂度:O(log(min(m,n))) 空间复杂度:O(1)

代码语言:javascript
复制
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        if len(nums1) > len(nums2):
            nums1, nums2 = nums2, nums1
        m, n = len(nums1), len(nums2)
        left, right = 0, m
        total_left = (m + n + 1) // 2
        while left < right:
            i = (left + right + 1) // 2
            j = total_left - i
            if nums1[i-1] > nums2[j]:
                right = i - 1
            else:
                left = i
        i = left
        j = total_left - i
        nums1_left = float('-inf') if i == 0 else nums1[i-1]
        nums1_right = float('inf') if i == m else nums1[i]
        nums2_left = float('-inf') if j == 0 else nums2[j-1]
        nums2_right = float('inf') if j == n else nums2[j]
        if (m + n) % 2 == 1:
            return max(nums1_left, nums2_left)
        else:
            return (max(nums1_left, nums2_left) + min(nums1_right, nums2_right)) / 2
代码语言:javascript
复制
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if (nums1.length > nums2.length) {
            int[] temp = nums1;
            nums1 = nums2;
            nums2 = temp;
        }
        int m = nums1.length, n = nums2.length;
        int left = 0, right = m;
        int totalLeft = (m + n + 1) / 2;
        while (left < right) {
            int i = (left + right + 1) / 2;
            int j = totalLeft - i;
            if (nums1[i-1] > nums2[j]) {
                right = i - 1;
            } else {
                left = i;
            }
        }
        int i = left, j = totalLeft - i;
        int nums1Left = i == 0 ? Integer.MIN_VALUE : nums1[i-1];
        int nums1Right = i == m ? Integer.MAX_VALUE : nums1[i];
        int nums2Left = j == 0 ? Integer.MIN_VALUE : nums2[j-1];
        int nums2Right = j == n ? Integer.MAX_VALUE : nums2[j];
        if ((m + n) % 2 == 1) {
            return Math.max(nums1Left, nums2Left);
        } else {
            return (Math.max(nums1Left, nums2Left) + Math.min(nums1Right, nums2Right)) / 2.0;
        }
    }
}
代码语言:javascript
复制
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        if (nums1.size() > nums2.size()) {
            swap(nums1, nums2);
        }
        int m = nums1.size(), n = nums2.size();
        int left = 0, right = m;
        int total_left = (m + n + 1) / 2;
        while (left < right) {
            int i = (left + right + 1) / 2;
            int j = total_left - i;
            if (nums1[i-1] > nums2[j]) {
                right = i - 1;
            } else {
                left = i;
            }
        }
        int i = left, j = total_left - i;
        int nums1_left = i == 0 ? INT_MIN : nums1[i-1];
        int nums1_right = i == m ? INT_MAX : nums1[i];
        int nums2_left = j == 0 ? INT_MIN : nums2[j-1];
        int nums2_right = j == n ? INT_MAX : nums2[j];
        if ((m + n) % 2 == 1) {
            return max(nums1_left, nums2_left);
        } else {
            return (max(nums1_left, nums2_left) + min(nums1_right, nums2_right)) / 2.0;
        }
    }
};

成功没有捷径,但正确的方向和方法能让你的努力事半功倍。坚持每天解决一个问题,三个月后你会遇见不一样的自己。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-07-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 高频 50 题题目列表
  • 详细题解
    • 1. 两数之和 (Two Sum)
    • 2. 反转链表 (Reverse Linked List)
    • 3. 有效的括号 (Valid Parentheses)
    • 4. 买卖股票的最佳时机 (Best Time to Buy and Sell Stock)
    • 5. 二叉树的层序遍历 (Binary Tree Level Order Traversal)
    • 6. 最大子序和 (Maximum Subarray)
    • 7. 爬楼梯 (Climbing Stairs)
    • 8. 三数之和 (3Sum)
    • 9. 合并两个有序链表 (Merge Two Sorted Lists)
    • 10. 二叉树的最近公共祖先 (Lowest Common Ancestor of a Binary Tree)
    • 21. 数组中的第K个最大元素 (Kth Largest Element in an Array)
    • 22. 除自身以外数组的乘积 (Product of Array Except Self)
    • 23. 滑动窗口最大值 (Sliding Window Maximum)
    • 24. 寻找重复数 (Find the Duplicate Number)
    • 25. LRU缓存机制 (LRU Cache)
    • 26. 盛最多水的容器 (Container With Most Water)
    • 27. 合并区间 (Merge Intervals)
    • 28. 最长无重复子串 (Longest Substring Without Repeating Characters)
    • 29. 最长回文子串 (Longest Palindromic Substring)
    • 30. 前K个高频元素 (Top K Frequent Elements)
    • 31. 编辑距离 (Edit Distance)
    • 32. 最大矩形 (Maximal Rectangle)
    • 33. 二叉树中的最大路径和 (Binary Tree Maximum Path Sum)
    • 34. 实现 Trie (前缀树) (Implement Trie (Prefix Tree))
    • 35. 回文链表 (Palindrome Linked List)
    • 36. 二叉树的锯齿形层序遍历 (Binary Tree Zigzag Level Order Traversal)
    • 37. 环形链表 II (Linked List Cycle II)
    • 38. 合并K个升序链表 (Merge k Sorted Lists)
    • 39. 最长上升子序列 (Longest Increasing Subsequence)
    • 40. 打家劫舍 (House Robber)
    • 41. 打家劫舍 III (House Robber III)
    • 42. 搜索二维矩阵 II (Search a 2D Matrix II)
    • 43. 完全平方数 (Perfect Squares)
    • 44. 移动零 (Move Zeroes)
    • 45. 二叉树的序列化与反序列化 (Serialize and Deserialize Binary Tree)
    • 46. 字符串解码 (Decode String)
    • 47. 分割等和子集 (Partition Equal Subset Sum)
    • 48. 路径总和 III (Path Sum III)
    • 49. 回文子串 (Palindromic Substrings)
    • 50. 寻找两个正序数组的中位数 (Median of Two Sorted Arrays)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档