三步走,找最大坐标,在左边找,在右边找
先二分找最大值所在地;
然后在左半边二分的找目标(升序);
在右半边找目标(降序);
建立一个数组记录已访问节点,减少重复访问次数;
/**
* // 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 {
private:
vector<int> vised;
public:
int getval(int id, MountainArray &mou) {
if(vised[id] < 0) vised[id] = mou.get(id);
return vised[id];
}
int findInMountainArray(int target, MountainArray &mou) {
int n = mou.length(); vised = vector<int>(n, -1);
vised[0] = getval(0, mou), vised[n - 1] = getval(n - 1, mou);
if(target == vised[0]) return 0;
if(target < vised[0] && target < vised[n - 1]) return -1;
int l = 0, r = n - 1;
int max_pos = 0;
while(l <= r) {
int mid = (l + r ) >> 1;
int a = getval(mid - 1, mou), b = getval(mid, mou), c = getval(mid + 1, mou);
if(b > a && b > c) {
max_pos = mid;
break;
}
else if(b > a && b < c) l = mid + 1;
else r = mid;
}
l = 0, r = max_pos;
while(l <= r) {
int mid = (l + r) >> 1, a = getval(mid, mou);
if(a == target) return mid;
else if(a < target) l = mid + 1;
else r = mid - 1;
}
l = max_pos, r = n - 1;
while(l <= r) {
int mid = (l + r) >> 1, a = getval(mid, mou);
if(a == target) return mid;
else if(a < target) r = mid - 1;
else l = mid + 1;
}
return -1;
}
};