剑指offer:二维数组中的查找元素(python)

二维数组中的查找元素

题目位置(点击链接)
代码位置(点击链接)
题目:
在一个二维数组中,每一行元素都按照从左到右递增的顺序排序,每一列元素都按照从上到下递增的顺序排序。实现一个查找功能的函数,函数的输入为二维数组和一个整数,判断数组中是否含有该整数。 如图所示。
在这里插入图片描述

方法1:

思路:
硬做,遍历二维数组

class Solution(object):
    def searchMatrix(self, matrix, target):
        for i in range(len(matrix)):
            for j in range(len(matrix[i])):
                    if matrix[i][j] == target:
                        return True
        return False

方法2:

思路:
给定了一个矩阵,该矩阵不仅每行,每列都递增,而且每行的首位比前行的末位数字大时,可看成一位数组,利用二分查找。
注意:
二维矩阵与一维矩阵下标对应的关系:
下标为i和j的元素,data[i][j],为矩阵中的第icols+j(下标从0开始)个元素。
那么,若 i
cols+j == values 反求i和j的话, i=values/cols , j=values%cols

class Solution(object):
    def searchMatrix(self, matrix, target):
        if not matrix or target is None:
            return False
        rows = len(matrix)
        cols = len(matrix[0])
        low = 0
        high = rows * cols -1
        
        while(low<=high):
            mid = (low+high)/2
            num = matrix[mid/cols][mid%cols]
            if num == target:
                return True
            elif num < target:
                low = mid +1
            else:
                high = mid -1
                
        return False

方法3:

思路:
首先选取右上角的数字,如果该数字大于target,则该列均大于target,删除该列;如果该数字小于target,则该行全小于target,删除该行。
从右上角元素开始,至左下角元素前,不断判断右上角元素和target的关系,可以不断缩小查找范围。

class Solution(object):
    def searchMatrix(self, matrix, target):
        if not matrix or target is None:
            return False
        rows,cols = len(matrix),len(matrix[0])
        i,j = 0,cols - 1
        while i<rows and j>=0: 
            if matrix[i][j] == target:
                return True
            elif matrix[i][j] < target:
                i = i + 1
            else:
                j = j-1
        return False

涉及知识点

if matrix == None or target == None:和if not matrix or target is None:的区别是什么?

代码中经常会有变量是否为None的判断,有三种主要的写法:

  • 第一种是if x is None;
  • 第二种是if not x:;
  • 第三种是if not x is None(这句这样理解更清晰if not (x is None))

在Python中,None、空列表[]、空字典{}、空元组()、0等一系列代表空和无的对象会被转换成False。除此之外的其它对象都会被转化成True。

>>> x = 1  
>>> not x  
False  
>>> x = [1]  
>>> not x  
False  
>>> x = 0  
>>> not x  
True  
>>> x = [0]         # You don't want to fall in this one.  
>>> not x  
False  

因此在使用列表的时候,如果你想区分x==[]和x==None两种情况的话, 此时if not x:将会出现问题。
也许你是想判断x是否为None,但是却把x==[]的情况也判断进来了,此种情况下将无法区分。

>>> x = []  
>>> y = None  
>>>   
>>> x is None  
False  
>>> y is None  
True  
>>>   
>>> not x  
True  
>>> not y  
True  
>>>    
>>> not x is None  
>>> True  
>>>
>>> not y is None  
False  

只有None is None时才为True

>>> x=[]
>>> y=''
>>> z=0
>>> w=None

>>> x is None
False
>>> y is None
False
>>> z is None
False
>>> w is None
True

>>> not x
True
>>> not y
True
>>> not z
True
>>> not w
True

>>> not x is None
True
>>> not y is None
True
>>> not z is None
True
>>> not w is None
False

Python中is和==的区别

Python中对象包含的三个基本要素,分别是:id(身份标识)、type(数据类型)和value(值)。
is和==都是对对象进行比较判断作用的,但对对象比较判断的内容并不相同。

==比较操作符和is同一性运算符区别

==是python标准操作符中的比较操作符,用来比较判断两个对象的value(值)是否相等.

>>> a = 'cheesezh'
>>> b = 'cheesezh'
>>> a == b
True

is也被叫做同一性运算符,这个运算符比较判断的是对象间的唯一身份标识,也就是id是否相同。

>>> x = y = [4,5,6]
>>> z = [4,5,6]
>>> x == y
True
>>> x == z
True
>>> x is y
True
>>> x is z
False
>>>
>>> print id(x)
3075326572
>>> print id(y)
3075326572
>>> print id(z)
3075328140

只有数值型和字符串型的情况下,a is b才为True,当a和b是tuple,list,dict或set型时,a is b为False。

>>> a = 1 #a和b为数值类型
>>> b = 1
>>> a is b
True
>>> id(a)
14318944
>>> id(b)
14318944
>>> a = 'cheesezh' #a和b为字符串类型
>>> b = 'cheesezh'
>>> a is b
True
>>> id(a)
42111872
>>> id(b)
42111872
>>> a = (1,2,3) #a和b为元组类型
>>> b = (1,2,3)
>>> a is b
False
>>> id(a)
15001280
>>> id(b)
14790408
>>> a = [1,2,3] #a和b为list类型
>>> b = [1,2,3]
>>> a is b
False
>>> id(a)
42091624
>>> id(b)
42082016
>>> a = {'cheese':1,'zh':2} #a和b为dict类型
>>> b = {'cheese':1,'zh':2}
>>> a is b
False
>>> id(a)
42101616
>>> id(b)
42098736
>>> a = set([1,2,3])#a和b为set类型
>>> b = set([1,2,3])
>>> a is b
False
>>> id(a)
14819976
>>> id(b)
14822256
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值