题解
看到本题矩阵的性质,第一反应是使用两次二分查找。第一次查询, t a r g e t target target的所在行。第二次查询, t a r g e t target target的所在列。
两次二分查找
- 特判,若 m a t r i x matrix matrix为空或 m a t r i x [ 0 ] matrix[0] matrix[0]为空,主要应对 [ ] [] []和 [ [ ] ] [[]] [[]]。
- 初始化矩阵行数 m m m和列数 n n n。
- 初始化查询行的左右界,
l
=
0
l=0
l=0,
r
=
m
−
1
r=m-1
r=m−1,当
l
<
=
r
l<=r
l<=r时进入循环:
- m i d = ( l + r ) / / 2 mid=(l+r)//2 mid=(l+r)//2,若最后一行中 m a t r i x [ m i d ] [ n − 1 ] = = t a r g e t matrix[mid][n-1]==target matrix[mid][n−1]==target,直接返回 T r u e True True
- 如果 m a t r i x [ m i d ] [ n − 1 ] > t a r g e t matrix[mid][n-1]>target matrix[mid][n−1]>target,令 r = r − 1 r=r-1 r=r−1
- 否则,令 l = l + 1 l=l+1 l=l+1
- 若查询行的左界 l > m − 1 l>m-1 l>m−1,说明 t a r g e t target target大于所有数组元素,返回 F a l s e False False。
- 在
l
l
l行内,进行搜索,初始化查询列的左右界,
l
_
2
=
0
l\_2=0
l_2=0,
r
_
2
=
n
−
1
r\_2=n-1
r_2=n−1,当
l
_
2
<
=
r
_
2
l\_2<=r\_2
l_2<=r_2时进入循环:
- m i d _ 2 = ( l _ 2 + r _ 2 ) / / 2 mid\_2=(l\_2+r\_2)//2 mid_2=(l_2+r_2)//2,在 i i i行中 m a t r i x [ i ] [ m i d _ 2 ] = = t a r g e t matrix[i][mid\_2]==target matrix[i][mid_2]==target,直接返回 T r u e True True
- 如果 m a t r i x [ i ] [ m i d _ 2 ] > t a r g e t matrix[i][mid\_2]>target matrix[i][mid_2]>target,令 r _ 2 = r _ 2 − 1 r\_2=r\_2-1 r_2=r_2−1
- 否则,令 l _ 2 = l _ 2 + 1 l\_2=l\_2+1 l_2=l_2+1。
- 返回 F a l s e False False。
复杂度分析
- 时间复杂度: O ( log ( m n ) ) O(\log (mn)) O(log(mn))。查找所在行 O ( log ( m ) ) O(\log (m)) O(log(m)),查找所在列 O ( log ( n ) ) O(\log (n)) O(log(n)) 。总体 O ( log ( m ) ) + O ( log ( n ) ) = O ( log ( m n ) ) O(\log (m))+O(\log (n))=O(\log (mn)) O(log(m))+O(log(n))=O(log(mn))
- 空间复杂度: O ( 1 ) O(1) O(1)
Python
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
if(not matrix or not matrix[0]):
return False
m=len(matrix)
n=len(matrix[0])
l=0
r=m-1
while(l<=r):
mid=(l+r)//2
if(matrix[mid][n-1]==target):
return True
elif(matrix[mid][n-1]>target):
r=r-1
else:
l=l+1
if(l>m-1):
return False
l_2=0
r_2=n-1
while(l_2<=r_2):
mid_2=(l_2+r_2)//2
if(matrix[l][mid_2]==target):
return True
elif(matrix[l][mid_2]>target):
r_2-=1
else:
l_2+=1
return False
Java(待完成)
一次二分查找
有点二维数组压缩的感觉。参考官方题解,发现可将二维矩阵映射到一维上。图片来自官方题解。
由图可知,一位数组中索引为
i
d
x
idx
idx对应二维矩阵中
r
o
w
row
row,
c
o
l
col
col位置的元素,对应关系如下:
行
r
o
w
=
i
d
x
/
/
n
row = idx // n
row=idx//n
列
c
o
l
=
i
d
x
col = idx % n
col=idx
算法流程
- 特判,若 m a t r i x matrix matrix为空或 m a t r i x [ 0 ] matrix[0] matrix[0]为空,主要应对 [ ] [] []和 [ [ ] ] [[]] [[]]。
- 初始化矩阵行数 m m m和列数 n n n。初试化查询左右界 l = 0 l=0 l=0, r = m ∗ n − 1 r=m*n-1 r=m∗n−1。
- 循环条件,当
l
<
=
r
l<=r
l<=r时进入循环:
- m i d = ( l + r ) / / 2 mid=(l+r)//2 mid=(l+r)//2,若 m a t r i x [ m i d / / n ] [ m i d % n ] = = t a r g e t matrix[mid//n][mid\%n]==target matrix[mid//n][mid%n]==target,直接返回 T r u e True True
- 如果 m a t r i x [ m i d / / n ] [ m i d % n ] > t a r g e t matrix[mid//n][mid\%n]>target matrix[mid//n][mid%n]>target,令 r = r − 1 r=r-1 r=r−1
- 否则,令 l = l + 1 l=l+1 l=l+1
- 返回 F a l s e False False
复杂度分析
- 时间复杂度: O ( M ∗ N ) O(M*N) O(M∗N)
- 空间复杂度: O ( 1 ) O(1) O(1)
Python
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
if(not matrix or not matrix[0]):
return False
m=len(matrix)
n=len(matrix[0])
l=0
r=m*n-1
while(l<=r):
mid=(l+r)//2
if(matrix[mid//n][mid%n]==target):
return True
elif(matrix[mid//n][mid%n]>target):
r=r-1
else:
l=l+1
return False