面试算法题精选 — 高频题目解析

适用人群:面试准备、算法练习
学习时长:约1-2周集中刷题
题目来源:LeetCode高频题
难度:Easy ~ Medium

一、数组类题目

1.1 两数之和(LeetCode #1)

# 题目:给定数组和目标值,找到两个数使其和等于目标值
# 方法:哈希表
def two_sum(nums, target):
    seen = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in seen:
            return [seen[complement], i]
        seen[num] = i
    return []

# 时间复杂度:O(n)
# 空间复杂度:O(n)

1.2 三数之和(LeetCode #15)

# 题目:找到所有和为0的三元组
# 方法:排序 + 双指针
def three_sum(nums):
    nums.sort()
    result = []
    for i in range(len(nums) - 2):
        if i > 0 and nums[i] == nums[i-1]:
            continue
        left, right = i + 1, len(nums) - 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

# 时间复杂度:O(n²)

1.3 最大子序和(LeetCode #53)

# 题目:找到具有最大和的连续子数组
# 方法:动态规划
def max_subarray(nums):
    max_sum = current_sum = nums[0]
    for num in nums[1:]:
        current_sum = max(num, current_sum + num)
        max_sum = max(max_sum, current_sum)
    return max_sum

# 时间复杂度:O(n)


二、链表类题目

2.1 反转链表(LeetCode #206)

# 方法:迭代
def reverse_list(head):
    prev = None
    current = head
    while current:
        next_node = current.next
        current.next = prev
        prev = current
        current = next_node
    return prev

# 方法:递归
def reverse_list_recursive(head):
    if not head or not head.next:
        return head
    new_head = reverse_list_recursive(head.next)
    head.next.next = head
    head.next = None
    return new_head

2.2 合并两个有序链表(LeetCode #21)

def merge_two_lists(l1, l2):
    dummy = ListNode(0)
    current = dummy
    while l1 and l2:
        if l1.val <= l2.val:
            current.next = l1
            l1 = l1.next
        else:
            current.next = l2
            l2 = l2.next
        current = current.next
    current.next = l1 or l2
    return dummy.next

2.3 环形链表(LeetCode #141)

# 方法:快慢指针
def has_cycle(head):
    if not head or not head.next:
        return False
    slow = head
    fast = head.next
    while slow != fast:
        if not fast or not fast.next:
            return False
        slow = slow.next
        fast = fast.next.next
    return True


三、字符串类题目

3.1 有效的括号(LeetCode #20)

def is_valid(s):
    stack = []
    mapping = {')': '(', ']': '[', '}': '{'}
    for char in s:
        if char in mapping:
            if not stack or stack[-1] != mapping[char]:
                return False
            stack.pop()
        else:
            stack.append(char)
    return not stack

3.2 最长回文子串(LeetCode #5)

# 方法:中心扩展法
def longest_palindrome(s):
    if len(s) < 2:
        return s
    
    start, max_len = 0, 1
    
    def expand(left, right):
        while left >= 0 and right < len(s) and s[left] == s[right]:
            left -= 1
            right += 1
        return left + 1, right - left - 1
    
    for i in range(len(s)):
        l1, len1 = expand(i, i)      # 奇数长度
        l2, len2 = expand(i, i + 1)  # 偶数长度
        
        if len1 > max_len:
            start, max_len = l1, len1
        if len2 > max_len:
            start, max_len = l2, len2
    
    return s[start:start + max_len]


四、树类题目

4.1 二叉树的最大深度(LeetCode #104)

# 方法:递归
def max_depth(root):
    if not root:
        return 0
    return 1 + max(max_depth(root.left), max_depth(root.right))

# 方法:BFS
from collections import deque
def max_depth_bfs(root):
    if not root:
        return 0
    depth = 0
    queue = deque([root])
    while queue:
        depth += 1
        for _ in range(len(queue)):
            node = queue.popleft()
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
    return depth

4.2 对称二叉树(LeetCode #101)

def is_symmetric(root):
    if not root:
        return True
    
    def is_mirror(left, right):
        if not left and not right:
            return True
        if not left or not right:
            return False
        return (left.val == right.val and 
                is_mirror(left.left, right.right) and 
                is_mirror(left.right, right.left))
    
    return is_mirror(root.left, root.right)


五、动态规划

5.1 爬楼梯(LeetCode #70)

def climb_stairs(n):
    if n <= 2:
        return n
    dp = [0] * (n + 1)
    dp[1] = 1
    dp[2] = 2
    for i in range(3, n + 1):
        dp[i] = dp[i-1] + dp[i-2]
    return dp[n]

# 空间优化
def climb_stairs_optimized(n):
    if n <= 2:
        return n
    a, b = 1, 2
    for _ in range(3, n + 1):
        a, b = b, a + b
    return b

5.2 买卖股票的最佳时机(LeetCode #121)

def max_profit(prices):
    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

5.3 零钱兑换(LeetCode #322)

def coin_change(coins, amount):
    dp = [float('inf')] * (amount + 1)
    dp[0] = 0
    
    for i in range(1, amount + 1):
        for coin in coins:
            if coin <= i:
                dp[i] = min(dp[i], dp[i - coin] + 1)
    
    return dp[amount] if dp[amount] != float('inf') else -1


六、排序算法

6.1 快速排序

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

6.2 归并排序

def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return merge(left, right)

def merge(left, right):
    result = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result.extend(left[i:])
    result.extend(right[j:])
    return result


七、刷题建议

第1周:数组和字符串(10题)
第2周:链表和栈(10题)
第3周:树和图(10题)
第4周:动态规划(10题)
第5周:综合练习(10题)

每天1-2题,坚持比数量更重要
理解算法思想,不要死记代码
做完看题解,学习最优解法
定期复习,防止遗忘


学习资源

返回首页