力扣经典算法题解析与实战指南

一、基础运算:A+B问题解析

作为算法入门题,A+B问题要求计算两个整数的和。该题看似简单,却隐含着对输入输出处理、边界条件判断等基础能力的考察。

1.1 题目核心要点

  • 数据范围:1≤t≤100组测试数据,每组数据包含两个1≤n≤1000的正整数
  • 输入处理:需支持多组测试用例的连续输入
  • 输出要求:每组结果单独成行

1.2 代码实现方案

  1. def calculate_sum():
  2. t = int(input()) # 读取测试用例数量
  3. for _ in range(t):
  4. a, b = map(int, input().split())
  5. print(a + b)
  6. calculate_sum()

1.3 扩展思考

该问题可扩展为:

  • 处理浮点数相加
  • 支持N个数的求和运算
  • 添加输入合法性校验

二、数组操作:移除指定元素

移除数组中特定值的问题考验对数组原地修改的理解,是掌握指针操作的重要练习。

2.1 题目要求

  • 原地修改数组(空间复杂度O(1))
  • 返回新数组长度
  • 元素顺序可改变

2.2 双指针解法

  1. def remove_element(nums, val):
  2. k = 0 # 慢指针
  3. for i in range(len(nums)): # 快指针
  4. if nums[i] != val:
  5. nums[k] = nums[i]
  6. k += 1
  7. return k
  8. # 示例
  9. nums = [3,2,2,3]
  10. print(remove_element(nums, 3)) # 输出: 2
  11. print(nums[:2]) # 输出: [2,2]

2.3 性能分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
  • 适用场景:大规模数据处理

三、数组变换:有序数组平方

该问题要求将非递减数组的每个元素平方后仍保持有序,涉及排序算法的选择与优化。

3.1 解题思路

  1. 暴力法:平方后重新排序(时间复杂度O(n log n))
  2. 双指针法:利用原数组有序特性(时间复杂度O(n))

3.2 优化实现

  1. def sorted_squares(nums):
  2. n = len(nums)
  3. result = [0] * n
  4. left, right = 0, n - 1
  5. for i in range(n-1, -1, -1):
  6. if abs(nums[left]) > abs(nums[right]):
  7. result[i] = nums[left] ** 2
  8. left += 1
  9. else:
  10. result[i] = nums[right] ** 2
  11. right -= 1
  12. return result
  13. # 示例
  14. print(sorted_squares([-4,-1,0,3,10])) # 输出: [0,1,9,16,100]

3.3 边界条件

  • 空数组处理
  • 全负数数组
  • 单元素数组

四、排序算法:数组升序排列

排序是算法基础中的基础,本题要求实现通用排序功能。

4.1 常见排序方案

算法 时间复杂度 空间复杂度 稳定性
冒泡排序 O(n²) O(1) 稳定
快速排序 O(n log n) O(log n) 不稳定
归并排序 O(n log n) O(n) 稳定

4.2 Python内置排序

  1. def sort_array(nums):
  2. return sorted(nums) # 使用Timsort算法
  3. # 示例
  4. print(sort_array([5,1,1,2,0,0])) # 输出: [0,0,1,1,2,5]

4.3 工业级实现建议

  • 小规模数据(n<50):插入排序
  • 大规模数据:快速排序或归并排序
  • 需要稳定性:归并排序

五、链表操作:移除指定节点

链表删除操作是数据结构基础,考验对指针操作的理解。

5.1 链表节点定义

  1. class ListNode:
  2. def __init__(self, val=0, next=None):
  3. self.val = val
  4. self.next = next

5.2 删除实现方案

  1. def remove_nodes(head, val):
  2. dummy = ListNode(0) # 创建虚拟头节点
  3. dummy.next = head
  4. prev, curr = dummy, head
  5. while curr:
  6. if curr.val == val:
  7. prev.next = curr.next
  8. else:
  9. prev = curr
  10. curr = curr.next
  11. return dummy.next

5.3 复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
  • 关键点:虚拟头节点简化边界条件处理

六、链表设计:自定义链表实现

本题要求实现完整的链表数据结构,考察面向对象编程能力。

6.1 单链表实现

  1. class MyLinkedList:
  2. def __init__(self):
  3. self.head = None
  4. self.size = 0
  5. def get(self, index):
  6. if index >= self.size or index < 0:
  7. return -1
  8. curr = self.head
  9. for _ in range(index):
  10. curr = curr.next
  11. return curr.val
  12. def add_at_head(self, val):
  13. self.add_at_index(0, val)
  14. def add_at_tail(self, val):
  15. self.add_at_index(self.size, val)
  16. def add_at_index(self, index, val):
  17. if index > self.size:
  18. return
  19. new_node = ListNode(val)
  20. if index == 0:
  21. new_node.next = self.head
  22. self.head = new_node
  23. else:
  24. prev = self.head
  25. for _ in range(index - 1):
  26. prev = prev.next
  27. new_node.next = prev.next
  28. prev.next = new_node
  29. self.size += 1
  30. def delete_at_index(self, index):
  31. if index >= self.size or index < 0:
  32. return
  33. if index == 0:
  34. self.head = self.head.next
  35. else:
  36. prev = self.head
  37. for _ in range(index - 1):
  38. prev = prev.next
  39. prev.next = prev.next.next
  40. self.size -= 1

6.2 设计要点

  • 边界条件处理(空链表、索引越界等)
  • 虚拟头节点简化操作
  • 维护size属性优化查询效率

七、数学计算:回文数判断

回文数问题考察数学运算与逻辑判断能力。

7.1 解题思路

  1. 字符串转换法:将数字转为字符串比较
  2. 数学运算法:通过取模运算反转数字

7.2 数学解法实现

  1. def is_palindrome(x):
  2. if x < 0 or (x % 10 == 0 and x != 0):
  3. return False
  4. reversed_num = 0
  5. original = x
  6. while x > 0:
  7. reversed_num = reversed_num * 10 + x % 10
  8. x = x // 10
  9. return original == reversed_num
  10. # 示例
  11. print(is_palindrome(121)) # 输出: True
  12. print(is_palindrome(-121)) # 输出: False

7.3 性能优化

  • 只需反转一半数字即可比较
  • 提前排除负数和末尾为0的非零数

八、算法学习建议

  1. 分阶段练习:从简单题入手,逐步提升难度
  2. 多解法对比:对每个问题尝试多种实现方式
  3. 边界条件测试:特别注意空输入、极值等特殊情况
  4. 时间复杂度分析:理解不同算法的效率差异
  5. 代码规范:保持变量命名清晰,添加必要注释

通过系统练习这些经典算法题,开发者可以建立扎实的算法基础,提升问题解决能力,为应对更复杂的编程挑战做好准备。建议每天坚持练习1-2道题目,并定期复习错题,形成完整的知识体系。