为什么二进制搜索适用于这个未排序的数组?

时间:2018-01-19 12:38:18

标签: java arrays recursion binary-search

考虑到这个问题: 峰值元素是一个大于其邻居的元素。

给定一个输入数组,其中num [i]≠num [i + 1],找到一个峰值元素并返回其索引。

数组可能包含多个峰,在这种情况下,将索引返回到任何一个峰都可以。

示例:Array = [1,4,5,7,4,3,1]。峰值指数= 3(即7)。

以下代码完美运行(不仅适用于此测试用例):

    public static int getPeakElement(int[] array, int left, int right) {

    if (left == right) {
        return left;
    }

    int mid = (left + right) / 2;

    if (array[mid] > array[mid + 1]) {
        return getPeakElement(array, left, mid);
    }

    return getPeakElement(array, mid + 1, right);
}   

我不明白它是如何工作的 - 我认为二进制搜索仅用于排序数组/旋转数组。

2 个答案:

答案 0 :(得分:2)

如果“峰值”的定义仅仅是它是一个比周围元素更大的元素,那么你可以推断出它的工作原理。

if (array[mid] > array[mid + 1]) {
    return getPeakElement(array, left, mid);
}

return getPeakElement(array, mid + 1, right);

条件是:

  • 如果mid元素大于相邻元素,则可能是峰值 - 它肯定比右边的元素大。在“左手”半边搜索一个至少同样大的峰值。
  • 否则,相邻元素可能是峰值 - 它肯定比它左边的元素大。在“右手”一半中搜索至少一个大的峰值。

随着递归的进行,您知道:

  • left-1在数组之外,或者元素小于arr[left]处的元素(否则你不会选择这一半)
  • right+1在数组之外,或者元素小于arr[right]处的元素(否则你不会选择这一半)。

你继续直到left == right,此时你知道你已达到峰值,因为相邻元素较少(或者你在阵列的一端或另一端)。

答案 1 :(得分:1)

如果有多个峰值,则不需要对数组进行排序。排序实际上会删除除一个峰值之外的所有峰值。

此代码如何工作?想象一下,你在一条不平坦的道路上,需要找到一个高峰 - 但你是盲目的,所以你看不到它,只能通过感觉工作。你从某个点开始,检查你是否必须向左或向右,取决于你所处的点的斜率(你左脚和右脚,感觉你击中了什么)。然后你迈出了一大步(你Miss Fantastic所以对你来说这个步骤不是问题)并再次检查新位置的坡度。你重复这个步骤,直到你到达左下坡的一个点,直到你达到一个高峰。