(这是一个 交互式问题 )所谓交互式问题就是需要使用自定义类型本身提供的接口!
给你一个 山脉数组 mountainArr,请你返回能够使得 mountainArr.get(index) 等于 target 最小 的下标 index 值。
如果不存在这样的下标 index,就请返回 -1。
// 升序
int binarySearch1(MountainArray &m, int lo, int hi, int target) {
if(lo > hi)
return -1;
int mid = (lo + hi) / 2;
int cur = m.get(mid);
if(cur == target)
return mid;
else if(cur < target)
return binarySearch1(m, mid + 1, hi, target);
return binarySearch1(m, lo, mid - 1, target);
}
// 降序
int binarySearch2(MountainArray &m, int lo, int hi, int target) {
if(lo > hi)
return -1;
int mid = (lo + hi) / 2;
int cur = m.get(mid);
if(cur == target)
return mid;
else if(cur < target)
return binarySearch2(m, lo, mid - 1, target);
return binarySearch2(m, mid + 1, hi, target);
}
int findPeakIndex(MountainArray &m, int lo, int hi) {
if (lo > hi)
return -1;
int mid = (lo + hi) / 2;
int cur = m.get(mid);
if (mid > 0 && mid < m.length() - 1 && m.get(mid - 1) < cur && cur > m.get(mid + 1))
return mid;
if (mid == 0 || m.get(mid - 1) < cur)
return findPeakIndex(m, mid + 1, hi);
return findPeakIndex(m, lo, mid - 1);
}
int findInMountainArray(int target, MountainArray &mountainArr) {
int peakIndex = findPeakIndex(mountainArr, 0, mountainArr.length() - 1);
int t1 = binarySearch1(mountainArr, 0, peakIndex, target);
if(t1 >= 0) return t1;
int t2 = binarySearch2(mountainArr, peakIndex, mountainArr.length() - 1, target);
return t2;
}
上面的代码显得有些累赘,其中两个二分查找是可以复用的,稍微做一点简化。
int binarySearch(MountainArray &m, int lo, int hi, int target, bool cmp(int, int)) {
if(lo > hi)
return -1;
int mid = (lo + hi) / 2;
int cur = m.get(mid);
if(cur == target)
return mid;
else if(cmp(cur, target))
return binarySearch(m, mid + 1, hi, target, cmp);
return binarySearch(m, lo, mid - 1, target, cmp);
}
int findPeakIndex(MountainArray &m, int lo, int hi) {
if (lo > hi)
return -1;
int mid = (lo + hi) / 2;
int cur = m.get(mid);
if (mid > 0 && mid < m.length() - 1 && m.get(mid - 1) < cur && cur > m.get(mid + 1))
return mid;
if (mid == 0 || m.get(mid - 1) < cur)
return findPeakIndex(m, mid + 1, hi);
return findPeakIndex(m, lo, mid - 1);
}
int findInMountainArray(int target, MountainArray &mountainArr) {
int peakIndex = findPeakIndex(mountainArr, 0, mountainArr.length() - 1);
int t1 = binarySearch(mountainArr, 0, peakIndex, target, [](int a, int b) ->bool { return a < b;});
if(t1 >= 0) return t1;
int t2 = binarySearch(mountainArr, peakIndex, mountainArr.length() - 1, target, [](int a, int b) ->bool {return a > b;});
return t2;
}