美文网首页
1095. 山脉数组中查找目标值

1095. 山脉数组中查找目标值

作者: 放下梧菲 | 来源:发表于2020-04-29 11:16 被阅读0次

    这是一个 交互式问题 )

    给你一个 山脉数组 mountainArr,请你返回能够使得 mountainArr.get(index) 等于 target 最小 的下标 index 值。

    如果不存在这样的下标 index,就请返回 -1。

    何为山脉数组?如果数组 A 是一个山脉数组的话,那它满足如下条件:

    首先,A.length >= 3

    其次,在 0 < i < A.length - 1 条件下,存在 i 使得:

    A[0] < A[1] < ... A[i-1] < A[i]
    A[i] > A[i+1] > ... > A[A.length - 1]

    你将 不能直接访问该山脉数组,必须通过 MountainArray 接口来获取数据:

    MountainArray.get(k) - 会返回数组中索引为k 的元素(下标从 0 开始)
    MountainArray.length() - 会返回该数组的长度

    注意:

    对 MountainArray.get 发起超过 100 次调用的提交将被视为错误答案。此外,任何试图规避判题系统的解决方案都将会导致比赛资格被取消。

    示例 1:

    输入:array = [1,2,3,4,5,3,1], target = 3
    输出:2
    解释:3 在数组中出现了两次,下标分别为 2 和 5,我们返回最小的下标 2。
    示例 2:

    输入:array = [0,1,2,4,2,1], target = 3
    输出:-1
    解释:3 在数组中没有出现,返回 -1。

    提示:

    3 <= mountain_arr.length() <= 10000
    0 <= target <= 10^9
    0 <= mountain_arr.get(index) <= 10^9

    本题虽然在力扣上标的是困难,但是我并不觉得这题的思想很复杂,其实是比较简单的二分查找思想。
    所谓的山脉数组其实就是一个有序的数组,前半部分直到峰顶是升序排序,后半部分是降序排序。
    因此我们可以通过二分查找法,先把峰顶给查出来,接着就是分别对前后两部分使用二分查找法来进行搜索数据,后面这块是比较简单的。
    如何通过二分查找法将峰顶查找出来呢,我来推演一下过程。
    以array = [1,2,3,4,5,3,1]为例子。
    当array[mid]<array[mid+1]的时候说明峰值一定在后面,因为峰值是最大值。
    反之的话就一定在前面。
    很简单的思路,一共是三次二分查找
    代码如下: 注意一次二分查找尽量减少get的调用,否则会无法通过

    /**
     * // 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 peek_index=findPeek(mountainArr);
            int ans1=bsfind(target,mountainArr,0,peek_index,true);
            if(ans1!=-1) return ans1;
            int ans2=bsfind(target,mountainArr,peek_index,mountainArr.length()-1,false);
            return ans2;
        }
        int bsfind(int target,MountainArray &mountainArr,int low,int high,bool ascending){
            if(ascending){
                while(low<=high){
                    int mid=(high-low)/2+low;
                    int tempMid=mountainArr.get(mid);
                    if(tempMid==target) return mid;
                    if(tempMid<target) low=mid+1;
                    if(tempMid>target) high=mid-1;
                }
                return -1;
            }
            else{
                while(low<=high){
                    int mid=(high-low)/2+low;
                    int tempMid=mountainArr.get(mid);
                    if(tempMid==target) return mid;
                    if(tempMid<target) high=mid-1;
                    if(tempMid>target) low=mid+1;
                }
                return -1;
            }
    
        }
        int findPeek(MountainArray &mountainArr){
            int low=0;
            int high=mountainArr.length()-1;
            while(low<high){
                int mid=(high-low)/2+low;
                if(mountainArr.get(mid)<mountainArr.get(mid+1)){//顶峰在后半部分
                    low=mid+1;
                }
                else{//顶峰在前半部分
                    high=mid;
                }
            }
            return low;
        }
    };
    

    摘自
    https://leetcode-cn.com/problems/find-in-mountain-array/

    相关文章

      网友评论

          本文标题:1095. 山脉数组中查找目标值

          本文链接:https://www.haomeiwen.com/subject/yvfywhtx.html