Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 来自谷歌的采访问题_Algorithm - Fatal编程技术网

Algorithm 来自谷歌的采访问题

Algorithm 来自谷歌的采访问题,algorithm,Algorithm,可能重复: 在谷歌的采访中,有人问了以下问题: 您将获得一个二维数组,该数组存储整数,并进行垂直和水平排序 编写一个方法,将整数作为输入并输出一个bool,说明该整数是否在数组中 最好的方法是什么?它的时间复杂度是多少?从矩阵的左下角开始,按照以下规则遍历矩阵: 矩阵遍历基于以下条件: 如果输入的数字大于当前数字:向右移动 如果输入数字小于当前数字:向上移动 如果输入编号等于当前编号:返回成功 如果输入编号不等于当前编号且无法转换:ReturnFail 时间复杂性:(感谢Martinho Fe

可能重复:

在谷歌的采访中,有人问了以下问题:

您将获得一个二维数组,该数组存储整数,并进行垂直和水平排序

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


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

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

矩阵遍历基于以下条件:

  • 如果输入的数字大于当前数字:向右移动
  • 如果输入数字小于当前数字:向上移动
  • 如果输入编号等于当前编号:返回成功
  • 如果输入编号不等于当前编号且无法转换:ReturnFail
  • 时间复杂性:(感谢Martinho Fernandes)

    时间复杂度为O(N+M)。在最坏的情况下,搜索的元素位于左上角,这意味着您将向上移动N次,向左移动M次

    示例

    输入矩阵:

    --------------
    | 1 | 4 | 6  | 
    --------------
    | 2 | 5 | 9  |
    --------------
    | *3* | 8 | 10 |
    --------------
    
    要搜索的编号:4

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

    3<4:向右移动


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


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


    第4步:


    4=4:返回数字的索引

    想到的第一种方法是垂直二进制搜索,当您找到它应该在的行时,紧接着是水平二进制搜索。复杂性将是
    O(log NM)
    ,其中
    N
    M
    是数组的维度

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

    我将首先询问“垂直和水平排序”的详细含义

    如果矩阵的排序方式是每行的最后一个元素小于下一行的第一个元素,则可以在第一列上运行二进制搜索以找出该数字在哪一行,然后在该行上运行另一个二进制搜索。此算法将花费O(logc+logr)时间,其中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
    
    在这种情况下,您可以同时运行某种水平和垂直二进制搜索:

  • 测试第一列的中间数字。如果它小于目标,考虑上面的线。如果它更大,考虑下面那些;<李>
  • 测试第一行的中间编号。如果它少了,考虑它左边的列。如果它更大,考虑右边的;<李> <车床,冲洗,重复,直到找到一个,否则你就没有更多的因素要考虑了;<李>
    这个方法也是元素数的对数。

    问题是……?它是按哪种方式排序的(即左->右,上->下=最小->最大)?完全重复:为什么这样做?它的时间复杂性是什么?对于面试问题,证明你的推理是特别重要的。我认为你混淆了左右。很好的解决方案。@Ravi:时间复杂度是O(N+M)。在最坏的情况下,搜索的元素位于左上角,这意味着您将向上移动N次,向左移动M次。@Martinho:谢谢!包括在回答中它可以有很多行。它不必在一行中。垂直二进制搜索将给出它应该在的行。如何通过二进制搜索找到它应该在的行?您无法保证它会出现在搜索返回的行中。@| \/| ad根据问题,它是垂直排序的,这意味着高于某个数字的每个数字都小于或等于该数字,反之亦然。因为我们知道,二进制搜索所指示的位置上的每一个数都小于该数,并且在所指示的位置之下的每个数都较大,它必须在相同的垂直位置,也就是相同的行。考虑具有行>1>2×3×3×4×100×4 5 1000</代码>的矩阵。我们要搜索
    100
    。二进制搜索将返回最后一行,
    100
    不是最后一行的一部分。接下来呢?你怎么能找到它在哪一行?我认为这是行不通的,因为仅仅看第一列是无法知道它是否会排成一行的。你可以知道它是否肯定不会排成一行,但这没有多大帮助。
    | 1 | 4 | 6  | 
    --------------
    | 2 | *5* | 9  |
    --------------
    | 3 | 8 | 10 |
    --------------
    
    | 1 | *4* | 6  | 
    --------------
    | 2 | 5 | 9  |
    --------------
    | 3 | 8 | 10 |
    --------------
    
    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