Local Minimum of an array

Problem: Given an array ‘a’ of N distinct integers, design an O(log N) algorithm to find a local minimum: an index i such that a[i-1] > a[i] < a[i+1].

数组的局部最小值: 定义局部最小的概念。arr长度为1时,arr[0]是局部最小。arr的长度为N(N>1)时,如果arr[0]<arr[1],那么arr[0]是局部最小;如果arr[N-1]<arr[N-2],那么arr[N-1]是局部最小;如果0<i<N-1,既有arr[i]<arr[i-1]又有arr[i]<arr[i+1],那么arr[i]是局部最小。

给定无序数组arr,已知arr中任意两个相邻的数都不相等,写一个函数,只需返回arr中任意一个局部最小出现的位置即可。

Solution:

If a[0] < a[1] or a[N - 2] > a[N - 1] then a[0] or a[N - 1] is the local minimum, respectively. Pick a[mid] where mid = N / 2. If it's not the answer, we have three cases:

1) If a[mid - 1] < a[mid] < a[mid + 1], lower half will contain the local minimum.

2) If a[mid - 1] > a[mid] > a[mid + 1], upper half will contain the local minimum.

3) If a[mid - 1] < a[mid] > a[mid + 1], either half will contain the local minimum.

Search on the new interval recursively.

Explanation:

If a[1] < a[2], a[1] is an LM. Otherwise, if a[n-1] > a[n], a[n] is an LM. Otherwise, the array entries start out descending (going from a[1] to a[2]) and ends up ascending (going from a[n-1] to a[n]). It follows that an LM must exist somewhere in between. Examine a[n/2]. If a[n/2] > a[n/2+1], then by the same reasoning there is an LM in the upper half of the array. Similarly, if a[n/2] < a[n/2+1] there is an LM in the lower half of the array. Solve recursively in the appropriate half.

public class LocalMinimum {

    public static int findLocalMinimum(int[] elements, int lowIndex, int highIndex) {
        if (lowIndex > highIndex) {
            return -1;
        }

        if (lowIndex == highIndex) {
            return lowIndex;
        }

        if (lowIndex + 1 == highIndex) {
            if (elements[lowIndex] < elements[highIndex]) {
                return lowIndex;
            }
            return highIndex;
        }

        int midIndex = (lowIndex + highIndex) / 2;

        if ((elements[midIndex] <= elements[midIndex - 1])
                && (elements[midIndex] <= elements[midIndex + 1])) {
            return midIndex;
        }

        if (elements[midIndex] >= elements[midIndex + 1]) {
            return findLocalMinimum(elements, midIndex, highIndex);
        } else {
            return findLocalMinimum(elements, lowIndex, midIndex);
        }
    }

    public static void main(String[] args){
        int Arr[] = {8,5,4,3,1,2,6,9};
        int index = findLocalMinimum(Arr, 0, Arr.length-1);
        System.out.println("local mimimum is "+Arr[index]);
    }

}

From 牛客网

此题的关键在于根据中间元素的大小对数组进行二分 解法的时间复杂度为 O(log n)

public static int findLocalMinimum(int[] arr) {
        if ( arr.length == 0 )
            return -1;

            // Size 为 1 直接 return, 不会执行第二个判断
        else if ( arr.length == 1 || arr[0] < arr[1] )
            return 0;

        if ( arr[arr.length - 1] < arr[arr.length - 2] )
            return arr.length - 1;

        int left = 1;
        int right = arr.length - 2;
        int mid = 0;

        while ( left < right ) {
            mid = (left + right ) >> 1;
            if ( arr[mid] > arr[mid - 1] ) {
                right = mid - 1;
            } else if ( arr[mid] > arr[mid + 1] ) {
                left = mid + 1;
            } else {
                return mid;
            }
        }
        return left;
}

results matching ""

    No results matching ""