如何在O(n)中找到排序数组中给定数字和的两个数字?

时间:2017-01-21 08:18:06

标签: java algorithm search big-o

public static void findNumber(int number) {
    int[] soretedArray = { 1, 5, 6, 8, 9 };
    for (int i = 0; i <= soretedArray.length; i++) {
        for (int j = i + 1; j < soretedArray.length; j++) {
            if (soretedArray[i] + soretedArray[j] == number) {
                System.out.println(soretedArray[i] + "::" + soretedArray[j]);
                return;
            }
        }
    }
}

使用此代码我能够找到数字,其复杂度为O(N ^ 2),但我必须使用O(N)复杂度找到它,即在Java中只使用一个for循环或哈希映射或类似。

3 个答案:

答案 0 :(得分:2)

我记得,我正在观看有关此问题的官方Google视频。虽然没有在java中演示,但是在问题的不同变体中逐步解释。你一定要检查一下:

How to: Work at Google — Example Coding/Engineering Interview

答案 1 :(得分:2)

the Google video that Alexander G is linking to中所述,使用两个数组索引。将一个初始化为第一个元素(0),将另一个初始化为最后一个元素(sortedArray.length - 1)。在循环中,检查两个索引处的两个元素的总和。如果总和是您要查找的数字,那么您就完成了。如果它太高,你需要在其中一个索引处找到一个较小的数字;将右侧索引向左移动一步(因为数组已排序,这是正确的方法)。另一方面,如果得到的总和太低,则将左侧索引向右移动以获得更高的第一个加数。当两个指数相遇时,如果你还没有找到你想要的金额,那就没有了。此时,您已经通过循环n - 1次,因此算法在O(n)中运行。

我们应该首先检查前提条件,即数组是否真正排序。这也可以在O(n)中完成,因此这样做不会破坏任何要求。

如果您需要找到产生所需总和的所有可能数字对而不是仅仅一对,则算法可能需要改进。

当视频链接已经说过时,这个答案是多余的吗?首先,我的解释更短,所以如果它足够,你就没事了。最重要的是,如果视频被删除或只是移动到另一个网址,我的答案仍然会在这里。

答案 2 :(得分:1)

对于固定的number,对于数组中任何选定的x,您只需查找数组中是否number-x(请注意,您也可以绑定x) 。这不会给你O(n),但是O(n.log(n))。

也许通过评论如果你有a_ia_jj>i),取总结并与number进行比较,如果结果更大,那么下一个有趣的测试是使用a_(i-1)a_(j-1),如果结果较低,则下一个有趣的测试是a_(i+1)a_(j+1),会给线性时间提示吗?