LeetCode 1095 山脉数组中查找目标值——二分寻找极值

  • 链接 : 原题

  • 题意 : 给定一个山脉数组,即凸函数,寻找一个数值等于target的index。

  • 思路 :
    因为凸函数峰值的左右都是一个单调函数,所以只要找到峰值,再对两边分别进行二分查找就可。
    凹凸函数找峰值,本来我是想用三分查找的,但是三分查找能确定峰值是double类型,即连续函数才适用的。整数点构成的凹凸函数,三分查找只能缩减一个区间。例如此题 :牛客算法周周练4 E题装备合成
    所以本次学到了一种 二分凹凸函数找极值 的方法。

    对于一个区间 [l , r] ,mid1 = (l + r)/2,我们再寻找一个mid2 = mid1 + 1。如果mid1 的值 > mid2 的值,那么 [mid2 , r] 是一个递减的区间;否则 [l, mid1]是一个递增的区间。
    在这里插入图片描述
    这样最后就能确定一个峰值peak。
    最后再对左边递增区间二分查找,如果没找到再到右边二分查找。

  • 代码:

/**
 * // This is the MountainArray's API interface.
 * // You should not implement it, or speculate about its implementation
 * class MountainArray {
 *   public:
 *     int get(int index);
 *     int length();
 * };
 */

class Solution {
    
    
public:
    int findInMountainArray(int target, MountainArray &mountainArr) {
    
    
        int l = 0, r = mountainArr.length() - 1;
        while(r - l > 0){
    
    
            int mid1 = l + (r-l)/2;
            int mid2 = mid1 + 1;
            if(mountainArr.get(mid1) > mountainArr.get(mid2)){
    
    
                r = mid1;
            }else{
    
    
                l = mid2;
            }
        }
        int left = 0, right = l;
        int ans = -1;
        while(left <= right){
    
    
            int mid = (right + left)/2;
            if(mountainArr.get(mid) == target){
    
    
                ans = mid;
            }
            if(mountainArr.get(mid) > target){
    
    
                right = mid - 1;
            }else{
    
    
                left = mid + 1;
            }
        }
        if(ans == -1){
    
    
            left = l + 1, right = mountainArr.length() - 1;
            while(left <= right){
    
    
                int mid = (right + left)/2;
                if(mountainArr.get(mid) == target){
    
    
                    ans = mid;
                }
                if(mountainArr.get(mid) > target){
    
    
                    left = mid + 1;
                }else{
    
    
                    right = mid - 1;
                }
            }
        }
        return ans;
    }
};
  • 遇到的问题:
    (1)二分查找的判定条件以及 mid + 1 ,mid - 1等等太容易出错了。并且在单调区间内二分搜索的时候 mid = (l + r)/2,而不可是 l + (r-l)/2。
    (2)第二次查找的时候区间不一样。

Guess you like

Origin blog.csdn.net/qq_39763472/article/details/105850338