本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
240. 搜索二维矩阵 II
来源:力扣(LeetCode)
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。
示例 1:
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5 输出:true
示例 2:
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20 输出:false
提示:
-
m == matrix.length
-
n == matrix[i].length
-
1 <= n, m <= 300
-
<= matrix[i][j] <=
-
每行的所有元素从左到右升序排列
-
每列的所有元素从上到下升序排列
-
<= target <=
解题思路:
- 暴力法: 两层for循环,从上到下,从左到右遍历查找,该方法复杂度比较高,没有利用到有序这一性质;
- 二分查找:单行是有序的,可以利用二分查找的方法让其快一点;
- Z字形查找:利用从左到右有序增大,从上到下有序增大查找;以每行最右上角元素进行比较,判断属于哪一层哪一列;如果最右上角元素比目标值大,则表明在左下角的元素中,列数-1;如果目标值比最右上角元素要大,则行数+1;也可以先找到属于某一行,再在某一层之后进行顺序查找或者二分查找;但还是不如第一种方法逐渐缩小比较范围更好;
代码实现
暴力法
- python实现
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
n = len(matrix)
if n == 0:
return False
m = len(matrix[0])
for i in range(n):
for j in range(m):
if matrix[i][j] == target:
return True
return False
- c++实现
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int n = matrix.size();
if (n == 0)
return false;
int m = matrix[0].size();
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++) {
if (matrix[i][j] == target)
return true;
}
}
return false;
}
};
复杂度分析
- 时间复杂度:
- 空间复杂度:
二分法
- python实现
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
n = len(matrix)
if n == 0:
return False
m = len(matrix[0])
left = 0
right = m - 1
for i in range(n):
nums = matrix[i]
if self.binarySearch(nums, target, left, right):
return True
return False
def binarySearch(self, nums:List, target:int, left:int, right:int):
while left <= right:
mid = left + (right-left) // 2
if nums[mid] == target:
return True
elif nums[mid] > target:
right -= 1
else:
left += 1
return False
- c++实现
class Solution {
public:
bool binarySearch(vector<int>& nums, int target, int left, int right) {
while (left <= right) {
int mid = left + (right-left) / 2;
if (nums[mid] == target)
return true;
else if (nums[mid] > target)
right--;
else
left++;
}
return false;
}
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int n = matrix.size();
if (n==0)
return false;
int m = matrix[0].size();
for (int i = 0; i<n; i++) {
if (binarySearch(matrix[i], target, 0, m-1))
return true;
}
return false;
}
};
复杂度分析
- 时间复杂度:
- 空间复杂度:
优化,行列均二分查找
class Solution:
def searchMatrix(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
if len(matrix) == 0:
return False
row, col = len(matrix), len(matrix[0])
# iterate over matrix diagonals, from top-left to bottom-right
short_edge = min(row, col)
for i in range(short_edge):
row_found = self.binary_search(matrix, target, i, False)
col_found = self.binary_search(matrix, target, i, True)
if row_found or col_found:
return True
return False
def binary_search(self, matrix, target: int, start: int, vertical: bool) -> bool:
lo = start
hi = len(matrix) - 1 if vertical else len(matrix[0]) - 1
while lo <= hi:
mid = (lo + hi) // 2
if vertical: # search column
if matrix[mid][start] < target:
lo = mid + 1
elif matrix[mid][start] > target:
hi = mid - 1
else:
return True
else: # search row
if matrix[start][mid] < target:
lo = mid + 1
elif matrix[start][mid] > target:
hi = mid - 1
else:
return True
return False
Z字形查找
- python实现
class Solution:
def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
rows = len(matrix)
if rows == 0:
return False
cols = len(matrix[0])
if cols == 0:
return False
row = 0
col = cols - 1
while row < rows and col >= 0:
refer_num = matrix[row][col]
if refer_num == target:
return True
elif refer_num > target:
col -= 1
else:
row += 1
return False
- c++实现
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
int rows = matrix.size();
if(rows==0)
return false;
int cols = matrix[0].size();
if(cols==0)
return false;
int row = 0;
int col = cols-1;
while(row < rows && col >= 0) {
int refer_num = matrix[row][col];
if (refer_num==target)
return true;
else if(refer_num < target)
row++;
else
col--;
}
return false;
}
};
复杂度分析
- 时间复杂度:
- 空间复杂度: