寻求峰值

寻找中间值大于左右值,且时间复杂度为O(logN),想到使用折半查找。

折半查找

/*折半查找*/
int Binary_Search(int a*,int n,int key)
{
    int low,high,mid;
    low=1;     /*定义最底下标为记录首位*/
    high=n;    /*定义最高下标为记录末位*/
    while(low<=high)
    {
        mid=(low+high)/2;    /*折半*/
        if(key<a[mid])
            high=mid-1;
        if(key>a[mid])
            low=mid+1;
        else
            return mid;
    }
    return 0;
}

解决方案

先找到mid对应的元素nums[mid],然后判断是否比nums[mid-1]大,比nums[mid+1]小,来确定其是否是峰值。

如果是峰值,那么直接返回mid。

不是峰值,就需要重新确定low和high。

如果nums[mid]>nums[mid+1],那么峰值有可能出现在mid的左侧;反之可能出现在mid的右侧。通过这种策略来重新确定low和high。

主体代码:

    while (low < high){
            mid = (low + high) / 2; 
            if (nums[mid] > nums[mid - 1] && nums[mid] > nums[mid + 1]){
                return mid;
            }else {
                if (nums[mid] < nums[mid + 1]){
                    low = mid + 1;
                }else {
                    high = mid - 1;
                }
            }
        }

情况一

如果数组的长度小于3,那么就单独处理一下:

        if (length == 1){
            return 0;
        }
        if (length == 2){
            return nums[0] > nums[1] ? 0: 1;
        }

情况二

防止mid-1和mid+1越界,重新调整mid的位置:

            if (mid - 1 < 0){
                temp = 1;
            }
            if (mid + 1 == length){
                temp = -1;
            }
            mid += temp;

情况三

遇到递增或者递减的情况,即low和high相等

        if (low == high){
            return high;
        }

整体代码:

class Solution {
    public int findPeakElement(int[] nums) {
        int length = nums.length;
        int low = 0,high = length - 1,mid,temp = 0;
        if (length == 1){
            return 0;
        }
        if (length == 2){
            return nums[0] > nums[1] ? 0: 1;
        }
        while (low < high){
            mid = (low + high) / 2;
            if (mid - 1 < 0){
                temp = 1;
            }
            if (mid + 1 == length){
                temp = -1;
            }
            mid += temp;
            if (nums[mid] > nums[mid - 1] && nums[mid] > nums[mid + 1]){
                return mid;
            }else {
                if (nums[mid] < nums[mid + 1]){
                    low = mid + 1;
                }else {
                    high = mid - 1;
                }
            }
        }
        if (low == high){
            return high;
        }
        return -1;
    }
}

猜你喜欢

转载自blog.csdn.net/lyj2018gyq/article/details/85610867