Google采访中询问了以下内容:
您将获得一个存储整数的2D数组,垂直和水平排序。
编写一个方法,将整数作为输入,并输出
bool
表示整数是否在数组中。
最好的方法是什么?它的时间复杂度是多少?
答案 0 :(得分:19)
从矩阵的左下角角开始,按照下面的规则来遍历矩阵:
矩阵遍历基于以下条件:
时间复杂度(感谢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 |
--------------
第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:返回数字索引
答案 1 :(得分:6)
我首先会询问有关“垂直和水平排序”的含义的详细信息
如果矩阵的排序方式是每行的最后一个元素小于下一行的第一个元素,则可以在第一列上运行二进制搜索,以找出该行所在的行,并且然后在该行上运行另一个二进制搜索。该算法将采用O(log C + log R)时间,其中C和R分别是行数和列数。如果N是数组中元素的数量,则使用对数属性,可以将其写为O(log(C * R)),它与O(log 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
在这种情况下,您可以同时运行某种水平垂直二进制搜索:
此方法也是元素数量的对数。
答案 2 :(得分:0)
第一种想到的方法是垂直二进制搜索,当你找到它应该在的行时,后面跟一个水平搜索。复杂性将是O(log NM)
其中N
和{{1}是数组的维度。
进一步说明: 只考虑每一行的第一个数字。当您对指定数字的这些第一个数字执行二进制搜索时,如果您幸运,结果将是指定的数字,否则它将是指定数字前后的位置,具体取决于二进制搜索实现。一旦找到指定数字之间的第一个数字中的两个,就知道该数字在该行中,并且第二个二进制搜索将找到该行中的数字。