Leetcode 二分查找 1

题号直达: 35 搜索插入位置 | 74 搜索二维矩阵

LeetCode 35. 搜索插入位置 ↑

题目

简单。 给定一个排序数组和一个目标值,在数组中找到目标值并返回其索引;若目标值不存在,则返回它若按顺序插入时应处的下标。

要求: 算法时间复杂度为 O(log n)。

测试样例

  • 示例 1: nums = [1,3,5,6],target = 5
    输出:2

  • 示例 2: nums = [1,3,5,6],target = 2
    输出:1

  • 示例 3: nums = [1,3,5,6],target = 7
    输出:4

提示

  • 1 ≤ len(nums) ≤ 10^4
  • -10^4 ≤ nums[i] ≤ 10^4,nums 无重复元素且升序
  • -10^4 ≤ target ≤ 10^4

代码(Python):二分查找

在 [left, right] 上二分:命中 nums[mid] == target 时直接返回 mid;否则缩小区间。循环结束时 left 即为「第一个 ≥ target 的位置」,也就是插入位置(若未找到 target)。

class Solution(object):
    def searchInsert(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        N = len(nums)
        left = 0
        right = N - 1
        while left <= right:
            mid = (right + left) // 2
            if nums[mid] == target:
                return mid
            elif nums[mid] < target:
                left = mid + 1
            else:
                right = mid - 1
        return left

讲解视频(讲解视频文件 0408_1.mp4)

思路解析

  • 相等:nums[mid] == target 时,下标即为答案。
  • 缩小区间:nums[mid] < target 说明插入位置在右侧,left = mid + 1;否则 right = mid - 1。
  • 未命中:循环结束时 left > right,此时 left 是第一个「应插入」的下标(与 bisect_left 语义一致)。
  • 复杂度:每次区间减半,O(log n) 时间,O(1) 额外空间。

LeetCode 74. 搜索二维矩阵 ↑

题目

中等。 给定 m × n 整数矩阵,满足:

  1. 每一行从左到右非递减;
  2. 每一行的第一个数大于上一行最后一个数。

即把矩阵按行首尾相接摊平后,整体是升序的。给定整数 target,判断矩阵中是否存在该值。

提示

  • m == len(matrix),n == len(matrix[i])
  • 1 ≤ m, n ≤ 100(常见范围,以题目为准)
  • -10^4 ≤ matrix[i][j], target ≤ 10^4

代码(Python)解法一:从首列定位行 + 行内线性查找(O(m + n))

按每行首元素从上到下扫:若 target 等于某行首则命中;若 target 小于当前行首,则 target 只可能出现在上一行(若存在)。确定行后,在该行内从左向右比较;若某元素大于 target 则不存在。原稿用变量名 i 同时作行指针与行内下标,易混淆;下行内遍历改为 j,并在扫完该行后 return False。

class Solution(object):
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        n = len(matrix)
        i = 0
        while i <= n - 1:
            if target == matrix[i][0]:
                return True
            if target < matrix[i][0]:
                break
            i = i + 1
        if i == 0:
            return False
        row = i - 1
        to_search = matrix[row]
        for j in range(len(to_search)):
            if to_search[j] == target:
                return True
            if to_search[j] > target:
                return False
        return False

思路解析(解法一)

  • 首列单调:各行首元素递增,故第一个满足 matrix[i][0] > target 的行号 i 将 target 限制在第 i-1 行(若 i=0 说明 target 小于最小元素,直接不存在)。
  • 行内:该行有序,线性扫描可二分优化为 O(log n);整体亦可对摊平序列做一次二分 O(log(mn))。
  • 复杂度:最坏 O(m + n) 时间,O(1) 额外空间。

代码(Python)解法二:摊平成一维后二分

矩阵按行展开后整体升序,下标 0 … m·n - 1 上二分。中间位置 mid 对应元素 matrix[mid // n][mid % n](n 为列数),与一维有序数组二分相同。

class Solution(object):
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        m = len(matrix)
        n = len(matrix[0])
        low = 0
        high = m * n - 1

        while low <= high:
            mid = (high - low) // 2 + low
            x = matrix[mid // n][mid % n]
            if x < target:
                low = mid + 1
            elif x > target:
                high = mid - 1
            else:
                return True

        return False

思路解析(解法二)

  • 下标映射:第 k 个元素在第 k // n 行、第 k % n 列(n 为每行长度)。
  • 二分:比较 x 与 target 缩小区间,满足题面 O(log(m·n)) 要求。
  • 复杂度:时间 O(log(m·n)),额外空间 O(1)。
posted @ 2026-10-12 00:20  Phier  阅读(4)  评论(0)    收藏  举报