74. 搜索二维矩阵(Search a 2D Matrix)

题解

看到本题矩阵的性质,第一反应是使用两次二分查找。第一次查询, t a r g e t target target的所在行。第二次查询, t a r g e t target target的所在列。

两次二分查找

  1. 特判,若 m a t r i x matrix matrix为空或 m a t r i x [ 0 ] matrix[0] matrix[0]为空,主要应对 [ ] [] [] [ [ ] ] [[]] [[]]
  2. 初始化矩阵行数 m m m和列数 n n n
  3. 初始化查询行的左右界, l = 0 l=0 l=0, r = m − 1 r=m-1 r=m1,当 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][n1]==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][n1]>target,令 r = r − 1 r=r-1 r=r1
    • 否则,令 l = l + 1 l=l+1 l=l+1
  4. 若查询行的左界 l > m − 1 l>m-1 l>m1,说明 t a r g e t target target大于所有数组元素,返回 F a l s e False False
  5. l l l行内,进行搜索,初始化查询列的左右界, l _ 2 = 0 l\_2=0 l_2=0, r _ 2 = n − 1 r\_2=n-1 r_2=n1,当 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_21
    • 否则,令 l _ 2 = l _ 2 + 1 l\_2=l\_2+1 l_2=l_2+1
  6. 返回 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

算法流程

  1. 特判,若 m a t r i x matrix matrix为空或 m a t r i x [ 0 ] matrix[0] matrix[0]为空,主要应对 [ ] [] [] [ [ ] ] [[]] [[]]
  2. 初始化矩阵行数 m m m和列数 n n n。初试化查询左右界 l = 0 l=0 l=0 r = m ∗ n − 1 r=m*n-1 r=mn1
  3. 循环条件,当 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=r1
    • 否则,令 l = l + 1 l=l+1 l=l+1
  4. 返回 F a l s e False False

复杂度分析

  • 时间复杂度: O ( M ∗ N ) O(M*N) O(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*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

Java(待完成)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值