面试题04. 二维数组中的查找(Python3)

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

示例:

现有矩阵 matrix 如下:

[
  [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]
]
给定 target = 5,返回 true。

给定 target = 20,返回 false。

解题思路:

因为每行每列都按照从大到小顺序排列,所以可以有如下思路:

对第i行,这一行最大的数必然是i[-1],最小的数必然是i[0],因此从第一行开始对每行进行遍历:

  • 如果target>该行最大数,则target必然在下一行或不存在,故直接遍历下一行即可,即pass;
  • 如果target<该行最小数,则target必然在之前的行,又因为是从第一行开始遍历的,所以必然不存在,返回False;
  • 如果target不属于上面两种情况,那么target可能在这一行,也可能在下一行,也可能不存在。下面对这一行按列遍历:
    •     如果target等于当前行当前列的数,则返回True;
    •     如果target大于当前行当前列的数,那么应该继续遍历下一个数,即pass;
    •     如果target小于当前行当前列的数,那么target要么不存在要么就在下一行,因此应该break;

当所有行遍历完成后,如果还没找到target,则说明不存在,返回False。

class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
        # matrix[1][1]; matrix[-1][-1]
        if len(matrix):
            if len(matrix[0]):
                m_min = matrix[0][0]
                m_max = matrix[-1][-1]
                if target < m_min or target > m_max:
                    return False
                else:
                    rows = len(matrix)
                    cols = len(matrix[0])
                    for index in range(rows):
                        r_max = matrix[index][-1]
                        r_min = matrix[index][0]
                        if target > r_max:  # 大于该行最大数,则必在后面的行
                            pass
                        elif target < r_min:  # 小于最小数,则必不存在
                            return False
                        else:               # 否则target要么在这一行,要么在下一行
                            for c_index in range(cols):
                                if matrix[index][c_index] == target:    # 就是这个
                                    return True
                                elif matrix[index][c_index] < target:   # 继续下一个
                                    pass
                                else:                                   # 大于情况一旦出现说明不在这一行
                                    break
                    return False # 遍历完成后还没找到则不存在
            else:
                return False
        else:
            return False

 

问题总结:

1. 逻辑比较复杂,需要想清楚;

2. 对List[List[int]]的操作不太熟,还要坚持做题;

3. 对特殊情况的排除,即matrix=[]和matrix=[[]];

 

做题过程中出现过的错误及最后结果:

 

 

执行结果:通过

执行用时:56 ms, 在所有 Python3 提交中击败了32.04%的用户

内存消耗:17.8 MB, 在所有 Python3 提交中击败了100.00%的用户

 

 

看到的另一种巧妙的解法:(链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/solution/gao-su-jie-fa-qing-xi-tu-jie-by-ml-zimingmeng/)

从左下角开始遍历,当该值小于 target 值时,向右搜索;大于 target 值时,向上搜索。如果找到 target 则返回 True,否则返回 False。

妙啊!

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

R.X. NLOS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值