【问题标题】:An interview question from Google [duplicate]来自谷歌的面试问题 [重复]
【发布时间】:2011-07-06 22:52:09
【问题描述】:

可能重复:
Given a 2d array sorted in increasing order from left to right and top to bottom, what is the best way to search for a target number?

在一次 Google 采访中被问到以下问题:

给定一个存储整数的二维数组,垂直和水平排序。

编写一个将整数作为输入并输出bool 的方法,说明该整数是否在数组中。

最好的方法是什么?它的时间复杂度是多少?

【问题讨论】:

标签: algorithm


【解决方案1】:

从矩阵的左下角开始,按照以下规则遍历矩阵:

矩阵遍历基于以下条件:

  1. 如果输入的数字大于当前数字:移动
  2. 如果输入的数字小于当前数字:上移
  3. 如果输入数字等于当前数字:返回成功
  4. 如果输入的数字不等于当前数字并且不可能进行转换:返回失败

时间复杂度:(感谢 Martinho Fernandes)

时间复杂度为O(N+M)。在最坏的情况下,搜索的元素在左上角,这意味着你会向上 N 次,离开 M 次。

示例

输入矩阵:

--------------
| 1 | 4 | 6  | 
--------------
| 2 | 5 | 9  |
--------------
| *3* | 8 | 10 |
--------------

要搜索的数字:4

第 1 步: 从有 3 的单元格开始(左下角)。

3


| 1 | 4 | 6  | 
--------------
| 2 | 5 | 9  |
--------------
| 3 | *8* | 10 |
--------------

第 2 步: 8 > 4:向上移动


| 1 | 4 | 6  | 
--------------
| 2 | *5* | 9  |
--------------
| 3 | 8 | 10 |
--------------

第 3 步: 5 > 4:向上移动


| 1 | *4* | 6  | 
--------------
| 2 | 5 | 9  |
--------------
| 3 | 8 | 10 |
--------------

第 4 步:

4=4:返回数字的索引

【讨论】:

  • 为什么会这样?它的时间复杂度是多少?对于面试问题,证明你的推理是特别重要的。
  • 我觉得你左右混淆了。否则很好的解决方案。
  • @Ravi:时间复杂度为 O(N+M)。在最坏的情况下,搜索的元素在左上角,这意味着您将向上 N 次,并离开 M 次。
  • @Martinho:谢谢!将其包含在答案中
【解决方案2】:

我将首先询问有关“垂直和水平排序”意味着什么的详细信息

如果矩阵的排序方式是每行的最后一个元素小于下一行的第一个元素,您可以对第一列运行二进制搜索以找出该数字在哪一行,并且然后在该行上运行另一个二进制搜索。该算法将花费 O(log C + log R) 时间,其中 C 和 R 分别是行数和列数。使用对数的属性,可以将其写为 O(log(C*R)),如果 N 是数组中的元素数,则与 O(log N) 相同。这与将数组视为一维数组并对其进行二分查找几乎相同。

但是矩阵可以按照每行最后一个元素不小于下一行第一个元素的方式排序:

1 2 3 4 5 6 7 8  9
2 3 4 5 6 7 8 9  10
3 4 5 6 7 8 9 10 11

在这种情况下,您可以同时运行某种水平和垂直二分搜索:

  1. 测试第一列的中间数字。如果它小于目标,请考虑它上面的行。如果更大,请考虑以下内容;
  2. 测试第一个考虑的行的中间数。如果它更少,请考虑它左侧的列。如果它更大,请考虑右边的那些;
  3. 车床、冲洗、重复,直到找到一个,否则您将没有更多需要考虑的元素;

这种方法也是元素数量的对数。

【讨论】:

  • 你怎么能找到它在哪一行?我认为这行不通,因为仅通过查看第一列无法知道它是否会连续排列。你可以知道它是否肯定不会连续出现,但这并没有多大帮助。
【解决方案3】:

想到的第一种方法是垂直二分搜索,然后是水平二分搜索,当你找到它应该在的行时。复杂度将是O(log NM),其中NM 是数组。

进一步说明: 只考虑每行的第一个数字。当您对指定数字执行这些第一个数字的二进制搜索时,如果幸运,结果将是指定的数字,否则它将是指定数字之前或之后的位置,具体取决于二进制搜索实现.一旦找到指定数字应该介于其间的前两个数字,您就知道该数字在该行中,如果该数字在该行中,则第二次二进制搜索将找到该数字。

【讨论】:

  • 它可能有很多行。它没有必要应该排成一行。
  • 垂直二分搜索将给出它应该在的行。
  • 如何通过二分查找找到它应该在的行?您无法保证它会出现在您的搜索返回的行中。
  • @|\/|ad 根据问题它是垂直排序的,这意味着高于某个数字的每个数字都小于或等于该数字,反之亦然。既然我们知道二分查找所指示的位置之上的每个数字都小于该数字而指示的位置之下的每个数字都更大,所以它必须在相同的垂直位置,也就是同一行。
  • 考虑矩阵1 2 3 | 3 4 100 | 4 5 1000。我们想搜索100。您的二分搜索将返回最后一行,而100 不属于最后一行。下一步是什么?
猜你喜欢
  • 2011-11-11
  • 2011-07-27
  • 2021-11-24
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 2019-02-05
  • 1970-01-01
相关资源
最近更新 更多