【剑指offer】04-二维数组中的查找

题目:

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。


思考:

1、遍历,用i, j分别遍历每行每列,找到相同的数据就返回True,没找到就返回False

class Solution:
    # array 二维列表
    def FindI(self, target, array):
        """一行一行的遍历"""
        m, n = len(array), len(array[0])  # m有多少行 n有多少列
        for i in range(0, m):
            for j in range(0, n):
                if array[i][j] == target:
                    return True
        return False  # 循环中所有都执行完了之后还没找到,才return False

写的过程中遇到的问题:

  一开始吧return False写在了循环里面,作为if  else的条件。但是这样的话,第一遍没找到数就会return False了。所以要把这句写在循环外面,二维数组中所有的都遍历完了之后,还没有找到该数,才返回False

该方案的缺点:

  每一个数都遍历,效率低

于是参考书籍,拥有方案2:

2、从右上角开始遍历,如果右上角的数值比target大 -> 该列都比target大,可以不用再继续比较该列的数值。

  如果右上角的数值比target小 -> 该行都比target小,可以不用再继续比较该行的数值。具体例子见图

    def FindII(self, target, array):
        """从右上角的元素开始找"""
        m, n = len(array), len(array[0])
        row, col = 0, n-1
        while row < m and col >= 0:
            if target < array[row][col]:
                col -= 1
            elif target > array[row][col]:
                row += 1
            else:
                return True
        return False

写的过程中遇到的问题:

  row一开始从1开始。遍历都是从0开始的。

  col一开始取值为n。跟上面一样,n是长度,但是遍历的时候,最后一个数的下标是n-1

  while循环条件不会。当行遍历到最后一行 且 列遍历到第一列(是从后往前遍历列)的时候,即到达了数组中左下角的那个数,都还没找到target,就退出循环。col可以取0。

该方法降低了时间复杂度,效率高。

为什么不从左上和右下开始遍历呢?

  -> 这有啥意义?左上开始,下边的和右边的都不能排除,还是得一行一行遍历。只有从右上或者左下开始,才有机会排除掉某行或某列的值。

其实还得关注一下每道题的测试用例【顺带训练测试思维呗】,这道题用例:

  二维数组每个边角的值:左上、左下、右上、右下。eg. 1、9、6、15

  中间的值:eg. 4、7

  不存在的值:eg. 100、99、空值

原文地址:https://www.cnblogs.com/RebeccaG/p/11924436.html