Leetcode1095.题目描述
给你一个 山脉数组 mountainArr,请你返回能够使得 mountainArr.get(index) 等于 target 最小 的下标 index 值。
如果不存在这样的下标 index,就请返回 -1。
何为山脉数组?如果数组 A 是一个山脉数组的话,那它满足如下条件:

注意:
对 MountainArray.get 发起超过 100 次调用的提交将被视为错误答案。


题目分析:
本题有点长,本文所给出的自定义的山峰数组数据类型,然后只留个两个接口,一个是长度,一个通过索引值返回对应值。然后山峰数组需要满足的条件就是,需要大于3,先升后降这样的,借用leetcode一张图,画出来就是下面这样。

解题思路:
峰值有什么特点呢,首先峰值的左边值和右边值都小于自己,这个特点和其他都不一样。依旧采用二分搜索,如果mid值小于mid+1呢,说明峰值在mid+1和r之间,如果大于呢,说明在[l,mid]之间,通过不断缩小方位,最终的l就对应峰值。
解决峰值后,在使用常规的二分就可以快速找到target是否存在,如果存在对应位置。代码如下:
#class MountainArray:
# def get(self, index: int) -> int:
# def length(self) -> int:
class Solution:
#先找峰值,然后二分搜索左边,如果有直接返回结果,如果返回-1,再搜右边,直接返回结果即可
def findInMountainArray(self, target: int, mountain_arr: 'MountainArray') -> int:
mid = self.findInMountainTop(mountain_arr)
l_idx = self.left_index(mid, mountain_arr,target)
if l_idx==-1:
return self.right_index(mid, mountain_arr,target)
else:
return l_idx
#二分搜索峰值的下标位置
def findInMountainTop(self,mountain_arr):
l = 0
r = mountain_arr.length()-1
while(l<r):
mid = (l+r)//2
if mountain_arr.get(mid)<mountain_arr.get(mid+1):
l = mid+1
else:
r = mid
return l
#二分搜索左边空间函数
def left_index(self, mid, mountain_arr,target):
l = 0
r = mid
while(l<r):
mid = (l+r)//2
if mountain_arr.get(mid)==target:
return mid
elif mountain_arr.get(mid)>target:
r = mid
else:
l = mid+1
return -1
#二分搜索右边空间函数
def right_index(self,mid,mountain_arr,target):
l = mid
r = mountain_arr.length()
while(l<r):
mid = (l+r)//2
if mountain_arr.get(mid)==target:
return mid
elif mountain_arr.get(mid)<target:
r = mid
else:
l = mid+1
return -1
