博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(python版)《剑指Offer》JZ01:二维数组中的查找
阅读量:4089 次
发布时间:2019-05-25

本文共 1984 字,大约阅读时间需要 6 分钟。

在这里插入图片描述
在这里插入图片描述

这道题的关键在于:

利用矩阵 “从上到下递增、从左到右递增” 的特点,建模为 二叉搜索树的查找 问题


【思路】将矩阵 转化为 二叉搜索树

  1. 利用矩阵 “从上到下递增、从左到右递增” 的特点,将矩阵逆时针旋转 45° ,并将其转化为图形式,发现其类似于 ,即对于每个元素,其左分支元素更小、右分支元素更大。

    因此,通过从 “根节点” 开始搜索,遇到比 target 大的元素就向左,反之向右,即可找到目标值 target
    在这里插入图片描述

  2. “根节点” 对应的是矩阵的 “左下角” 和 “右上角” 元素,本文称之为 标志数

    ①. 以 matrix 中的 左下角元素 为标志数 flag ,则有:

    若 flag > target ,则 target 一定在 flag 所在 行的上方 ,即 flag 所在行可被消去。

    若 flag < target ,则 target 一定在 flag 所在 列的右方 ,即 flag 所在列可被消去。

    ②. 以 matrix 中的 右下角元素 为标志数 flag ,则有:

    若 flag > target ,则 target 一定在 flag 所在 列的左方 ,即 flag 所在行可被消去。

    若 flag < target ,则 target 一定在 flag 所在 行的下方 ,即 flag 所在列可被消去。

  3. 选①的算法流程:

    1. 从矩阵 matrix 左下角元素(索引设为 (i, j) )开始遍历,并与目标值对比:

      i)   当 matrix[i][j] > target 时,执行 i-- ,即消去第 i 行元素;ii)  当 matrix[i][j] < target 时,执行 j++ ,即消去第 j 列元素;iii) 当 matrix[i][j] = target 时,返回 truetrue ,代表找到目标值。
    2. 若行索引或列索引越界,则代表矩阵中无目标值,返回 false。

      每轮 i 或 j 移动后,相当于生成了“消去一行(列)的新矩阵”, 索引(i,j) 指向新矩阵的左下角元素(标志数),因此可重复使用以上性质消去行(列)。

效果看图

在这里插入图片描述
在这里插入图片描述

【代码】

class Solution:    def findNumberIn2DArray(self,matrix,target):        i, j = len(matrix) - 1, 0     # 左下角        while i >= 0 and j < len(matrix[0]):            if matrix[i][j] > target:                 i -= 1            elif matrix[i][j] < target:                 j += 1            else:   # 找到为真                return True        return False'''作者:Krahets链接:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/5vl81e/来源:力扣(LeetCode)著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。'''

【复杂度分析】

  • 时间复杂度 O(M+N):其中,N 和 M 分别为矩阵行数和列数,此算法最多循环 M+N 次。
  • 空间复杂度 O(1) : i, j 指针使用常数大小额外空间。

【补充知识点】

  • len(矩阵) 返回的是 二维矩阵 的第一维长度

    在这里插入图片描述

  • 什么是二叉搜索树?

    在这里插入图片描述

【扩展】

若以 右下角元素 为标志数 flag
如果大的话,先收缩行;小的话,收缩列

class Solution:    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:		i, j = 0,len(matrix[0])-1           # 右上角        while i < len(matrix) and j >=0:            if matrix[i][j] > target: j -= 1            elif matrix[i][j] < target: i += 1            else: return True        return False

但右上角元素的坐标不好判断

在这里插入图片描述
发现先取 len(matrix[0]) 的值,才行。但是运行时间太慢了~

if not matrix: 		return False	m, n = len(matrix), len(matrix[0])
你可能感兴趣的文章
C++多态的实现方式总结
查看>>
学习C++需要注意的问题
查看>>
C++模板
查看>>
C++双冒号(::)的用法
查看>>
【Unity】封装SQLite管理类
查看>>
【Unity】面试题整理
查看>>
【C#】如何实现一个迭代器
查看>>
【Unity】Destroy和DestroyImmediate的区别
查看>>
【Lua】Mac系统下配置SublimeText的Lua编译环境
查看>>
【C#】利用Conditional属性完成编译忽略
查看>>
【Unity】微信登录后将头像存为bytes,将bytes读取成sprite图片
查看>>
【Unity】使用GPS定位经纬度
查看>>
【UGUI/NGUI】一键换Text/Label字体
查看>>
【C#】身份证本地验证
查看>>
【Unity】坑爹的Bug
查看>>
【算法】求数组中某两个数的和为目标值
查看>>
如何高效学习动态规划?
查看>>
动态规划法(六)鸡蛋掉落问题(一)
查看>>
LeetCode 887.鸡蛋掉落(C++)
查看>>
Dijkstra‘s algorithm (C++)
查看>>