返回
揭秘LeetCode 633:2D 方阵搜索的解题奥秘
前端
2023-12-10 05:52:08
LeetCode 633:2D 方阵搜索
LeetCode 633 是一个经典的二维数组搜索问题,旨在考察你对数组的搜索和遍历能力。题目如下:
给定一个二维矩阵 matrix 和一个目标值 target,请你在矩阵中搜索 target,并返回其在矩阵中的坐标。如果目标值不存在,则返回 [-1, -1]。
解题思路
对于此题,我们可以使用多种解法,每种解法都有其独特的优势和劣势。下面我们将介绍三种最常见的解法:
1. 线性搜索
最简单直接的解法是线性搜索。我们从矩阵的左上角开始,逐个元素地搜索目标值,直到找到它为止。如果搜索到矩阵的右下角都没有找到目标值,则返回 [-1, -1]。
def search_matrix(matrix, target):
for i in range(len(matrix)):
for j in range(len(matrix[0])):
if matrix[i][j] == target:
return [i, j]
return [-1, -1]
这种解法的优点是简单易懂,缺点是时间复杂度为 O(mn),其中 m 和 n 分别是矩阵的行数和列数。
2. 二分查找
如果矩阵是有序的,我们可以使用二分查找来提高搜索效率。二分查找的思想是将矩阵分成两半,然后在较小的那一半中继续搜索,如此反复,直到找到目标值为止。
def search_matrix(matrix, target):
left, right = 0, len(matrix) * len(matrix[0]) - 1
while left <= right:
mid = (left + right) // 2
row, col = mid // len(matrix[0]), mid % len(matrix[0])
if matrix[row][col] == target:
return [row, col]
elif matrix[row][col] < target:
left = mid + 1
else:
right = mid - 1
return [-1, -1]
这种解法的优点是时间复杂度为 O(log(mn)),比线性搜索快得多。缺点是要求矩阵是有序的。
3. 分治法
分治法的思想是将矩阵分成若干个子矩阵,然后在每个子矩阵中递归地搜索目标值。当子矩阵的大小为 1 时,直接返回该元素的值。
def search_matrix(matrix, target):
def search_submatrix(matrix, target, left, right):
if left > right:
return [-1, -1]
mid = (left + right) // 2
row, col = mid // len(matrix[0]), mid % len(matrix[0])
if matrix[row][col] == target:
return [row, col]
elif matrix[row][col] < target:
return search_submatrix(matrix, target, mid + 1, right)
else:
return search_submatrix(matrix, target, left, mid - 1)
return search_submatrix(matrix, target, 0, len(matrix) * len(matrix[0]) - 1)
这种解法的优点是时间复杂度也是 O(log(mn)),而且不需要矩阵是有序的。缺点是代码实现比二分查找要复杂一些。
复杂度分析
时间复杂度
- 线性搜索:O(mn)
- 二分查找:O(log(mn))
- 分治法:O(log(mn))
空间复杂度
所有解法的空间复杂度都是 O(1),因为它们都不需要额外的空间。
总结
LeetCode 633 是一道经典的二维数组搜索问题,考察了数组的搜索和遍历能力。我们可以使用多种解法来解决这个问题,每种解法都有其独特的优势和劣势。具体选择哪种解法,需要根据实际情况而定。