題目
(這是一個 交互式問題 )
給你一個 山脈數組 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 次調用的提交將被視為錯誤答案。此外,任何試圖規避判題系統的解決方案都將會導致比賽資格被取消。
為了幫助大家更好地理解交互式問題,我們準備了一個樣例 “答案”:https://leetcode-cn.com/playground/RKhe3ave,請注意這 不是一個正確答案。
示例 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
代碼
思路:
目標數組分為兩部分,前部分升序排列,后部分降序排序。
1.二分查找找到峰值的位置peek
2.二分在0-peek中查找target
3.若前部分未找到,則二分在peek+1-len-1中查找。
時間復雜度O(logN)三次二分查找;空間復雜度O(1)
/**
* // 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 len = mountainArr.length();
//找到峰頂
int l = 0,r = len-1;
int peek = 0;
while(l<=r){
int m = l+(r-l)/2;
if(m==0){
peek = 1;
break;
}
if(m==len-1){
peek = len - 2;
break;
}
int top = mountainArr.get(m);
if(top>mountainArr.get(m-1)&&top>mountainArr.get(m+1)){
peek = m;
break;
}else if(top>mountainArr.get(m-1)){
l = m+1;
}else{
r = m-1;
}
}
int index = binarySearch(target,mountainArr,0,peek,true);
if(index!=-1)
return index;
else
return binarySearch(target,mountainArr,peek+1,mountainArr.length()-1,false);
}
//二分查找 f標記是升序排列還是降序排列
public int binarySearch(int target,MountainArray mountainArr,int l,int r,boolean f){
while(l<=r){
int m = l+(r-l)/2;
int x = mountainArr.get(m);
if(x==target){
return m;
}else if(x>target){
if(f)
r = m-1;
else
l = m+1;
}else {
if(f)
l = m + 1;
else
r = m-1;
}
}
return -1;
}
}