行业资讯

二分查找算法精讲:从搜索插入位置到二维矩阵搜索

发布时间:2026/8/10 15:45:10
二分查找算法精讲:从搜索插入位置到二维矩阵搜索 1. 题目解析与核心思路Leetcode 143题实际上包含两个经典算法问题搜索插入位置Search Insert Position和搜索二维矩阵Search a 2D Matrix。这两个问题看似不同但核心都考察二分查找算法的灵活应用能力。1.1 搜索插入位置问题给定一个排序数组和一个目标值要求在数组中找到目标值的位置。如果目标值不存在则返回它将会被按顺序插入的位置。例如输入: nums [1,3,5,6], target 5 → 输出: 2输入: nums [1,3,5,6], target 2 → 输出: 11.2 搜索二维矩阵问题给定一个m×n的矩阵其中每行的元素从左到右升序排列每列的元素从上到下升序排列。要求判断目标值是否存在于矩阵中。例如[ [1, 4, 7, 11], [2, 5, 8, 12], [3, 6, 9, 16] ]输入: target 5 → 输出: true输入: target 10 → 输出: false2. 二分查找算法精讲2.1 标准二分查找实现二分查找的核心在于每次将搜索范围减半。标准实现需要注意三个关键点def binary_search(nums, target): left, right 0, len(nums) - 1 while left right: mid left (right - left) // 2 # 防止溢出 if nums[mid] target: return mid elif nums[mid] target: left mid 1 else: right mid - 1 return -1 # 未找到注意计算mid时使用left (right - left) // 2而非(left right) // 2可以避免整数溢出问题。2.2 变种搜索插入位置搜索插入位置是二分查找的变种关键在于处理未找到目标值时返回left指针def search_insert(nums, target): left, right 0, len(nums) - 1 while left right: mid left (right - left) // 2 if nums[mid] target: return mid elif nums[mid] target: left mid 1 else: right mid - 1 return left # 关键区别2.3 时间复杂度分析二分查找的时间复杂度为O(log n)空间复杂度为O(1)。对于m×n的二维矩阵如果采用两次二分查找先行后列时间复杂度为O(log m log n)。3. 二维矩阵搜索的三种解法3.1 两次二分查找法先对第一列进行二分查找确定行再在该行进行二分查找def searchMatrix(matrix, target): if not matrix or not matrix[0]: return False # 在第一列中查找合适的行 row bisect.bisect_right([row[0] for row in matrix], target) - 1 if row 0: return False # 在选定的行中进行二分查找 col bisect.bisect_left(matrix[row], target) return col len(matrix[row]) and matrix[row][col] target3.2 全局二分查找法将二维矩阵视为一维数组进行二分查找def searchMatrix(matrix, target): if not matrix or not matrix[0]: return False m, n len(matrix), len(matrix[0]) left, right 0, m * n - 1 while left right: mid left (right - left) // 2 num matrix[mid // n][mid % n] if num target: return True elif num target: left mid 1 else: right mid - 1 return False3.3 步进搜索法从矩阵右上角开始逐步向左下角移动def searchMatrix(matrix, target): if not matrix or not matrix[0]: 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: row 1 else: col - 1 return False4. 边界条件与常见错误4.1 空输入处理必须考虑矩阵为空或矩阵行/列为空的情况if not matrix or not matrix[0]: return False # 或适当返回值4.2 整数溢出问题计算mid时常见的错误写法mid (left right) // 2 # 可能溢出应改为mid left (right - left) // 24.3 循环终止条件while循环的条件应为left right而非left right否则可能漏判边界情况。5. 性能优化技巧5.1 提前终止在步进搜索法中一旦发现当前元素大于目标值且是行首元素或小于目标值且是列尾元素可以立即终止搜索。5.2 缓存友好访问在全局二分查找法中按行优先顺序访问元素比列优先更高效因为现代计算机的缓存机制对连续内存访问更友好。5.3 分支预测优化在二分查找的核心循环中将相等判断放在最前面可能提高分支预测成功率if nums[mid] target: return mid elif nums[mid] target: left mid 1 else: right mid - 16. 实际应用场景6.1 数据库索引查找二分查找是B树等数据库索引结构的核心算法理解其变种对优化查询性能至关重要。6.2 游戏中的碰撞检测在2D游戏中对排序后的物体坐标使用二分查找可以快速定位可能发生碰撞的对象。6.3 实时日志分析处理按时间排序的日志数据时二分查找可以快速定位特定时间范围内的事件。7. 扩展练习建议Leetcode 34在排序数组中查找元素的第一个和最后一个位置Leetcode 240搜索二维矩阵 II每行升序每列升序Leetcode 378有序矩阵中第K小的元素Leetcode 702搜索长度未知的有序数组在实际编码面试中面试官常常会基于这些基础问题进行变种考察。建议先彻底掌握标准二分查找的实现再逐步挑战各种变种问题。