LeetCode 1095

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

这个题标着hard,然而题目实质还是非常容易的,就是先用二分法找到中间的峰,然后再对左手边上升的数组和右手边下降的数组使用二分查找寻找target,最后返回两个之中较小的值。代码如下

/**
 * // This is MountainArray's API interface.
 * // You should not implement it, or speculate about its implementation
 * interface MountainArray {
 *     public int get(int index) {}
 *     public int length() {}
 * }
 */
 
class Solution {
    public int findInMountainArray(int target, MountainArray mountainArr) {
        int mid = findTop(mountainArr, 0, mountainArr.length()-1);
        int leftPlace =   findLeft(mountainArr, 0, mid,target);
        int rightPlace = findRight(mountainArr, mid+1, mountainArr.length()-1,target);
        return leftPlace==-1?rightPlace:rightPlace==-1?leftPlace:Math.min(leftPlace,rightPlace);
    }

    private int findTop(MountainArray mountainArr,int left, int right){
        int l = left;
        int r = right;
        int mid = 0;
        int leftNumber = 0;
        int midNumber = 0;
        while(l<r){
            mid = l + (r-l)/2;
            leftNumber = mountainArr.get(l);
            midNumber = mountainArr.get(mid);
            if(leftNumber<midNumber){
                if(midNumber < mountainArr.get(mid+1)){
                    l = mid+1;
                }else{
                    r = mid;
                }
            }else if(leftNumber == midNumber&& l == mid){
                break;
            }else{
                r = mid-1;
            }
        }
        return r;
    }

    private int findLeft(MountainArray mountainArr,int left, int right, int target){
        int l = left;
        int r = right;
        int mid = 0;
        int midNumber = 0;
        while(l<=r){
            mid = l + (r-l)/2;
            midNumber=mountainArr.get(mid);
            if(midNumber == target){
                return mid;
            }else if(midNumber>target){
                r = mid-1;
            }else{
                l = mid+1;
            }
        }
        return -1;
    }
    private int findRight(MountainArray mountainArr,int left, int right, int target){
        int l = left;
        int r = right;
        int mid = 0;
        int midNumber = 0;
        while(l<=r){
            mid = l + (r-l)/2;
            midNumber=mountainArr.get(mid);
            if(midNumber == target){
                return mid;
            }else if(midNumber>target){
                l = mid+1;
            }else{
                r = mid-1;
            }
        }
        return -1;
    }
}
View Code

我写代码已经算是比较复杂了,在寻找山峰的地方完全可以简化成如下的代码

        int left = 0, right = mountainArr.length()-1;
        while (left < right) {                  // 找到top点
            int mid = (left + right) / 2;
            if (mountainArr.get(mid) < mountainArr.get(mid + 1))    
                left = mid + 1;
            else
                right = mid;
        }

总的来说这次双100还是很爽的~~

posted @ 2020-04-29 10:25  ZJPang  阅读(168)  评论(0编辑  收藏  举报