Leetcode 解决方案 - 搜索 2D 矩阵

Leetcode 解决方案 - 搜索 2D 矩阵

为了帮助我了解你 填写此调查(匿名)

确保你真正理解这个即将到来的问题的解决方案。这个问题很特别,因为解决实际上并不需要太多的特殊知识。只是一些逻辑和最基本的代数。造成这个问题的原因不是解决方案有多难,而是发现要做什么需要一些洞察力。我喜欢这样的问题,因为它们非常适合测试你解决问题的能力。

这个问题可以发现为问题 74. 搜索二维矩阵 力科。

问题

编写一个搜索值的高效算法 目标 在一个 mxn 整数矩阵 矩阵 .该矩阵具有以下性质:

  • 每行中的整数从左到右排序。
  • 每行的第一个整数大于前一行的最后一个整数。

示例 1:

 输入:矩阵 = [[1,3,5,7],[10,11,16,20],[23,30,34,60]],目标 = 3  
 输出:真

示例 2:

 输入:矩阵 = [[1,3,5,7],[10,11,16,20],[23,30,34,60]],目标 = 13  
 输出:假

约束:

  • m == 矩阵.长度
  • n == 矩阵[i].length
  • 1 <= 米,n <= 100
  • -104 <= 矩阵[i][j],目标 <= 104

您可以在这里测试您的解决方案

第 1 步:使用蛮力

由于这个问题非常简单,我们可以进入蛮力解决方案。正如我们在我的时事通讯中多次谈到的那样,获得有效解决方案的最有影响力的方法之一是采用蛮力解决方案并从那里削减。

我们的蛮力看起来相对简单。我们将遍历矩阵,并逐个检查单元格。我们基本上是在整个二维数组上进行线性搜索。所需的时间复杂度为 O(m*n),因为我们需要检查每个值。我们也不会使用额外的空间。

我们该怎样改进这个?显然,我们并没有以任何方式真正使用矩阵的属性。这将是一个很好的下一步。让我们来看看我们能得出什么见解。

第 2 步:查看矩阵规则

我们有两个关于矩阵的特殊规则-

  • 每行中的整数从左到右排序。
  • 每行的第一个整数大于前一行的最后一个整数。

结合起来,这告诉我们一些有趣的事情—— 该矩阵按行优先顺序排序。 这个术语对你来说可能是新的,但看看下面,你会发现这通常是我们使用嵌套 for 循环遍历二维数组时使用的顺序。确保你在面试中灵活运用这个术语,以获得那些甜蜜的布朗尼分数。

取自这里。 Some of the most beautiful documentation I’ve ever seen.

现在,大多数在线解决方案都使用了这种洞察力,并且对此做的很少。他们运行二进制搜索两次,一次是为了识别正确的行,另一次是为了找到正确的列。这还不错,但这是一种非常笨拙的做事方式。您必须运行的代码将比必要的长得多。我将与您分享的内容更易于编写代码,并且只需要多做一点工作即可。如果您将经常使用矩阵(大多数专业软件开发人员),那么了解这种技术是必须的。

Hint: This is what we would like to do. 图片来源

第 3 步:在 1D 和 2D 之间转换

记住我们是如何对蛮力解决方案进行这个简单观察的——” 我们基本上是在整个二维数组上进行线性搜索 ”?这就是这个简单的陈述成为解决这个棘手问题的关键的地方。如果有办法评估我们的二维数组 作为排序的一维数组 ,然后我们可以在整个事情上只运行一次我们的信任伙伴二进制搜索。

我们实际上可以将 2D 矩阵“展平”为 1D 列表,反之亦然。那些熟悉机器学习的人(或任何非常擅长矩阵的人)都会知道这一点。对于那些真正想炫耀你的知识的人-知道 我们可以将任何 n 维张量重塑为任何其他维度 .你问什么是张量? 在数学中,一个 ** 张量** 是一个代数对象,描述了与向量空间相关的代数对象集之间的多线性关系。 用更简单的话来说,将其视为多维矩阵。如果列表是一条线,矩阵是一个正方形,张量可以是从线到正方形、立方体等的任何东西。

Tensors can have any number of dimensions. 资源

只要记住在谈论张量时保持非常强烈的眼神交流。这会引起面试官的恐惧,并自动将您标记为关系中的 Alpha。如果您在执行此操作时“编织”迈克泰森风格,则会获得奖励积分。

回到这个问题,重塑矩阵是一项昂贵的操作。但我们需要的只是索引(运行我们的搜索)。如果我们能找出一些规则来识别二维矩阵中的给定位置在我们的(想象的)重构列表中的位置,那么我们就可以有效地在整个矩阵上运行我们的二分搜索。让我们开始吧。

第4步:找出deets

让我们研究一下在索引之间切换的规则。为此,我们将使用本时事通讯中最喜欢的技术,使用小型测试输入。

让我们采用遵循给我们的规则的矩阵 [ [1,2,3] [4,5,6]]。我们知道要运行我们的二分搜索解决方案,我们需要列表 [1,2,3,4,5,6]。索引 [1][0] 需要变为 3,依此类推。这种转换也需要反向进行,即索引 0 变为 [0][0],idx 3 变为 [1][0] 等等。让我们看看我们是否可以计算出一些基本的数学方程式来匹配这些条件。让我们首先解决从 2D 到 1D 的展平问题。

应该清楚的是,第一行将保持它们的列索引相同。从 [0][0] 到 [0][2] 的索引将从 0 到 2。下一行将从 3-5 开始。

 更一般地,给定一个 m 列和 n 行的矩阵-  
 第一行将从 0 变为 (m-1),  
 第 2 行 - m 至 (2m-1)  
 第 3 排 - 2m 至 (3m-1)  
 ...  
 第 n 行 - (n-1)*m 到 (nm-1)  
 如果我们的扁平数组在索引中

随意测试这一点以自己确认。有了这些信息,我们能做什么?

 给定矩阵中的位置 [r][c]  
 一维数组中的索引-  
 r*m+ c = middleIdx

让我们测试一下。在我们的玩具数组中给定 [1][0],我们返回 13 + 0= 3。给定 [1][2] 我们得到 13 + 2=5。两个值都签出。让我们举一个更大的例子。考虑一个 5x5 矩阵,在适当的索引处具有从 0 到 24 的值。

 开始时  
 [0][0]- 0*5 + 0 = 0  
 [1][0]- 1*5+ 0 = 5  
 [3][4]- 3*5 + 4= 19  
 [4][4]- 4*5 + 4= 24

到目前为止,一切都很好。使用这个我们可以逆向设计规则来计算我们扁平数组中给定中间索引的行和列索引 -

 c=middleIdx-r*m  
 r= (middleIdx-c)/m

由于我们得到了 m,因此计算比您想象的要容易得多。 c 只是 middleIdx%m 而 r 是 middleIdx//m ('//' 代表整数除法。它截断浮动部分,只留下 int。3//2 = 1)。花点时间了解原因。如果你有困难,你知道如何联系我。

一旦我们弄清楚了,我们所有的部分现在都会到位。是时候进入编码了。

第 5 步:编码

我们的代码将做以下事情-

  1. 让开始索引为 0,结束为 row*col(这将是我们展平数组的长度)
  2. 使用这些指针计算中间索引。
  3. 使用上述规则将中间索引转换为适当的 2D 位置。
  4. Rest 是一个标准的二分搜索

实际上,我们已经把它变成了一个正常的二分搜索,稍作修改。这比替代方案更容易使用。

 类解决方案:  
 def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:  
 如果不是矩阵:  
 返回假  
 行 = 长度(矩阵)  
 col = len(matrix[0]) # 矩阵的列数...  
 乞求 = 0  
 end = row*col #将其视为一维矩阵  
 而乞求<结束:  
 mid = beg + (end - beg) // 2  
 idx = matrix[mid // col][mid % col];  
 如果 idx == 目标:  
 返回真  
 如果 idx < 目标:  
 乞求 = 中 + 1  
 别的:  
 结束 = 中间  
 返回假

时间复杂度- O(log(m*n)) = O(log(m)+ log(n))

空间复杂度 - O(1)

有关更多此类解决方案,请查看我的时事通讯 技术面试变得简单 . Tech Made Simple 是希望在科技领域建立惊人职业生涯的人们的最佳资源。它将帮助您构思、构建和优化您的解决方案。 它涵盖了从系统设计、计算机科学概念和 Leetcode 问题解决等技术方面到有关网络和建立职业生涯的详细指南的所有内容 . 通过在一个地方找到满足您的所有需求来节省您的时间、精力和金钱。 使用此处的链接可获得 20% 的折扣,最多可享受一整年 .

我建立 技术面试变得简单 使用通过指导多人进入顶级科技公司而发现的新技术。时事通讯旨在帮助您取得成功,让您免于浪费在 Leetcode 上的时间。 我有一个 100% 满意的政策,所以你可以毫无风险地尝试一下 . 您可以阅读常见问题解答并在此处了解更多信息

如果您也对我有任何有趣的工作/项目/想法,请随时与我联系。总是很高兴听到你的声音。

我的 Venmo 和 Paypal 为我的工作提供资金支持。任何金额都会受到赞赏并有很大帮助。捐款解锁论文解析、专题代码、咨询、专项辅导等独家内容:

文莫: https://account.venmo.com/u/FNU-Devansh

贝宝: paypal.me/ISeeThings

联系我

使用下面的链接查看我的其他内容,了解有关辅导的更多信息,或者只是打个招呼。此外,请查看免费的 Robinhood 推荐链接。我们都得到了一个免费的股票(你不必投入任何资金),你没有风险。 所以不使用它只会损失免费的钱。

查看我在 Medium 上的其他文章。 : https://rb.gy/zn1aiu

我的 YouTube: https://rb.gy/88iwdd

在 LinkedIn 上与我联系。让我们连接: https://rb.gy/m5ok2y

我的Instagram: https://rb.gy/gmvuy9

我的推特: https://twitter.com/Machine01776819

如果您正在准备编码/技术面试: https://codinginterviewsmadesimple.substack.com/

获得 Robinhood 的免费股票: https://join.robinhood.com/fnud75

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/11140/20590210

posted @   哈哈哈来了啊啊啊  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示