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; } }
我写代码已经算是比较复杂了,在寻找山峰的地方完全可以简化成如下的代码
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还是很爽的~~