Search a 2D Matirx II

题目详情:https://leetcode.com/problems/search-a-2d-matrix-ii/description/

思路:
1、检查第一列的行首元素,从最后一行开始,如果行首元素小于等于target的行停止,假设该位置为row。target不可能在大于row的行中,因为大于row行中的元素都比target大。
2、检查第一行的列首元素,从最后一列开始,如果列首元素小于等于target,那么在该列停止。假设该列为column,target不可能在大于column的中,因为大于column的列的元素值都大于target
经过以上两步,就确定了target的大体范围,接下来就是在该范围内进行详细 查找,从第二行,第二列开始。
举个例子:

[
  [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]
]

在上面的矩阵中,查找9,即target=9。
1、首先从最后一行开始检查行首元素,row=m-1。18>9,row=row-1;10>9,row=row-1;3<=9满足题意。此时row为2。
2、从最后一列开始检查列首元素,column=n-1。15>9,column=column-1;
11>9,column=column-1;7<=9,满足条件,停止循环。此时column为2。
此时就能够确定target大体范围,即行范围(1,2),列范围(1,2)。然后在这个范围进行详细查找就可以了。

# -*- coding:utf-8 -*-
class Solution(object):
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        if not matrix:
            return False
        m,n=len(matrix),len(matrix[0])
        if n==0:
            return False
        row=m-1
        while row>=0:#检查每一行
            if target>=matrix[row][0]:#如果列首元素小于等于target
                break#那么停止循环,因为target所在的行只可能小于等于row
            row-=1
        column=n-1
        while column>=0:#检查每一列
            if target>=matrix[0][column]:#如果列首元素小于等于target
                break#停止循环,target所在的列只可能小于等于column
            column-=1
        #以上两个循环为找target的大体范围
        if matrix[row][0]==target or matrix[0][column]==target:#检查行首和列首元素,因为不检查第一行和第一列
            return True
        i,j=1,1#行,列从(1,1)开始
        #以下为开始循环,行循环的范围为(1,row),列循环的范围为(1,column)
        while i<=row:
            j=1
            while j<=column:
                if matrix[i][j]==target:
                    return True
                j+=1
            i+=1
        return False

但是这种方法的效率太低,我就开始考虑别的方法了。既然一开始就可以缩小范围,那么为什么不可以把范围缩小到只有一个元素呢?由此想到的思路就是循环探测“行首“和“列首“的过程。
举个例子:

[
  [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]
]

在上面的矩阵查找9,即target=9。
第一次循环结束后,row=2,column=2。
第二次循环,去掉第一行和第一列,并且矩阵的行数,列数为2、2,即我们要访问的矩阵为

[
    [5,8],
    [6,9]
]

然后再依次检查该矩阵的行首元素和列首元素。从最后一行开始检查行首元素,6<=9成立,结束循环,此时的row为1(如果以上面的小矩阵为准的话,大矩阵的row为2);从最后一列开始检查列首元素,8<=9成立,结束循环,此时的column为1(同样以小矩阵为准)。第二次结束,此时row=1,column=1
第三次循环,去掉第一行,第一列,此时我们要访问的矩阵的行数,列数为1、1,即:

[
    [9]
]

这样就把范围缩小到只有一个元素了。这是思路,具体的实现会有点差异。
具体代码为:

# -*- coding:utf-8 -*-
class Solution(object):
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        if not matrix:
            return False
        m,n=len(matrix),len(matrix[0])
        if n==0:
            return False
        row,column,i=m-1,n-1,0#rowlimit和columnlimit用来存储行,列访问的上限,i存储访问的下界
        while i<=column and i<=row:#访问的下限不能超过上限
            while row>=i:#探测“行首”元素,并一定是真正的行首元素
                if target>=matrix[row][i]:#如果某行的“行首”,大于等于target
                    break#到这个地方停止
                row-=1
            while column>=i:#探测”列首”元素,同样的不一定为真正的列首元素
                if target>=matrix[i][column]:#如果某一列的列首语速小于等于target
                    break#到这个地方停止
                column-=1
            if row<i and column<i:#不存在这个元素
                return False
            if matrix[row][i]==target or matrix[i][column]==target:#探测'行首'和‘列首’处位置是否等于target,以免漏掉
                return True#则返回true
            i=i+1#访问下限加1
        return matrix[rowlimit][columnlimit]==target

上面这两种方法是自己想到的,两者有相似点。但是这两种方法的效率都不高。当我看到别人写的代码的时候,[吃惊]。厉害啊
代码如下:

# -*- coding:utf-8 -*-
class Solution(object):
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        if not matrix:
            return False
        m,n=len(matrix),len(matrix[0])
        if n==0:
            return False
        row,column=0,n-1
        while row<m and column>=0:
            if matrix[row][column]==target:#等于target则直接返回
                return True
            elif matrix[row][column]<target:#某一行的最后一个元素,其实也不一定是真正的最后一个元素,小于target
                row+=1#那么需要增大matrix[row][column]的值,故将row加1,因为此时的matrix[row][column]已经是最后一个元素了
            else:#matrix[row][column]>target,需要减小matrix[row][column]的值
                column-=1#将column减1
        return False#执行到这,说明没有找到
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值