Leetcode 二分查找 1
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 整数矩阵,满足:
- 每一行从左到右非递减;
- 每一行的第一个数大于上一行最后一个数。
即把矩阵按行首尾相接摊平后,整体是升序的。给定整数 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)。

浙公网安备 33010602011771号