一、寻找峰值
题目解析
对于这道题,给定一个数组
nums,在这数组中,可能存在多个峰值元素,我们只需找到一个峰值,然后返回峰值索引即可。峰值元素:严格大于左右相邻的元素。
题目中给定:
nums[0]和nums[n]可以看做负无穷。
算法思路
对于这道题,首先暴力解法:遍历整个数组,依次判断一个元素它是不是峰值元素。
暴力解法的时间复杂度是 O(n);并且暴力解法它并没有用到题目中给的:nums[0] 和 nums[n] 可以看做负无穷这一个条件。
当我们遍历 i 位置时,有且仅有两种情况:递增/递减(题目给定 nums[i] != nums[i+1])。
当
i位置呈现递增趋势时,也就是nums[i] > nums[i+1],题目又给出nums[0] = nums[n] = -∞区间[left, i]:也就是左侧区间内,因为最左侧是负无穷,所以左侧区间要么一直递增,要么既有递增也有递减(开始位置肯定是先递增在递减)。如果一直递增,那i位置就是一个峰顶;如果既有递增也有递减,那左侧区间内一定存在峰顶。也就是说,左侧区间内一定存在峰顶。区间[i+1, right]:也就是右侧区间,因为最右侧是负无穷,所以右侧区间可能一直递减,也可能既有递增也有递减。如果一直递减,那右侧区间就不存在峰顶(因为nums[i+1] < nums[i]);如果既有递增也有递减,那右侧区间是存在峰顶的。那也就是说,右侧区间不一定存在峰顶。同理,如果
i位置呈递减趋势,也就是nums[i] < nums[i+1]时:左侧区间不一定存在峰顶,右侧区间一定存在峰顶。所以,遍历
i位置时,就会把数组划分成区间[left, i]和区间[i+1, right];这两个区间一个是一定存在峰顶的,一个是不一定存在峰顶的。
所以我们就可以根据二段性,使用二分查找算法。
定义
left,right,取mid = left + (right - left) / 2如果nums[mid] > nums[mid+1]:左侧区间一定存在峰顶,去左侧区间查找 如果nums[mid] < nums[mid+1]:右侧区间一定存在峰顶,去右侧区间查找


