以下内容是在Google面试中提出的:
你有一个存储整数的二维数组,按垂直和水平方向排序。
编写一个方法,以整数作为输入,并输出一个布尔值,指示该整数是否在数组中。
最好的方法是什么?它的时间复杂度是多少?
以下内容是在Google面试中提出的:
你有一个存储整数的二维数组,按垂直和水平方向排序。
编写一个方法,以整数作为输入,并输出一个布尔值,指示该整数是否在数组中。
最好的方法是什么?它的时间复杂度是多少?
从矩阵的左下角开始遍历矩阵,按照以下规则进行:
矩阵遍历基于以下条件:
时间复杂度:(感谢 Martinho Fernandes)
时间复杂度为O(N+M)。在最坏情况下,要查找的元素在左上角,这意味着您将向上移动N次,向左移动M次。
示例
输入矩阵:
--------------
| 1 | 4 | 6 |
--------------
| 2 | 5 | 9 |
--------------
| *3* | 8 | 10 |
--------------
要查找的数字为:4
步骤1:从拥有数字3的单元格开始(左下角)。
3 < 4:向右移动
| 1 | 4 | 6 |
--------------
| 2 | 5 | 9 |
--------------
| 3 | *8* | 10 |
--------------
第二步: 8 > 4:向上移动
| 1 | 4 | 6 |
--------------
| 2 | *5* | 9 |
--------------
| 3 | 8 | 10 |
--------------
第三步: 5 > 4:向上移动
| 1 | *4* | 6 |
--------------
| 2 | 5 | 9 |
--------------
| 3 | 8 | 10 |
--------------
第四步:
4=4:返回该数的索引
我会先询问有关“垂直和水平排序”含义的详细信息。
如果矩阵按照每行的最后一个元素小于下一行的第一个元素的方式进行排序,您可以在第一列上运行二分搜索以找到该数字所在的行,然后在该行上再运行另一个二分搜索。这个算法将花费O(log C + log R)时间,其中C和R分别是行数和列数。利用对数的一个性质,可以将其写为O(log(C*R)),如果N是数组中元素的数量,则与将数组视为1D并在其上运行二分搜索几乎相同。
但是矩阵可能以每行的最后一个元素不小于下一行的第一个元素的方式进行排序:
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
在这种情况下,您可以同时运行某种水平和垂直二分搜索:
这种方法在元素数量上也是对数级的。
首先想到的方法是进行垂直二分查找,然后在找到应该在的行时进行水平查找。复杂度将为O(log NM)
,其中N
和M
是数组的维数。
进一步解释: 考虑每行的第一个数字。当您对这些第一个数字执行二分搜索以查找指定数字时,结果将是指定数字(如果您很幸运),否则它将是指定数字所在位置之前或之后的位置,具体取决于二分搜索实现方式。一旦找到了指定数字应该放置在其两个第一个数字之间的行,您就知道该数字在该行中,并且第二次二分搜索将在该行中查找该数字。
1 2 3 | 3 4 100 | 4 5 1000
。我们想要搜索 100
。您的二分查找将返回最后一行,而 100
不是该行的一部分。接下来怎么办? - IVlad