来自Google的采访问题

时间:2011-03-02 01:25:43

标签: algorithm

  

可能重复:
  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采访中询问了以下内容:

  

您将获得一个存储整数的2D数组,垂直和水平排序。

     

编写一个方法,将整数作为输入,并输出bool表示整数是否在数组中。

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

3 个答案:

答案 0 :(得分:19)

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

矩阵遍历基于以下条件:

  1. 如果输入的数字大于当前数字:移动向右
  2. 如果输入的数字小于当前数字:移动向上
  3. 如果输入的数字等于当前数字:返回成功
  4. 如果输入的数字不等于当前数字且无法转换:返回失败
  5. 时间复杂度(感谢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

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

  1. 测试第一列的中间数字。如果它小于目标,请考虑它上面的线。如果它更大,请考虑以下内容;
  2. 测试第一个考虑的行的中间数。如果它更少,请考虑它左边的列。如果它更大,请考虑右边的那些;
  3. 车床,冲洗,重复,直到找到一个,或者你没有更多元素需要考虑;
  4. 此方法也是元素数量的对数。

答案 2 :(得分:0)

第一种想到的方法是垂直二进制搜索,当你找到它应该在的行时,后面跟一个水平搜索。复杂性将是O(log NM)其中N和{{1}是数组的维度。

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