这题可以看做是证明:
当 nums[0] > nums[-1], nums[n-1] > nums[n], nums相邻数字不相等,1 <= nums.length 的时候,一定有解
证明方法采用归纳。
1. 当 n = 1,由题目条件可知其成立 nums[0] > nums[-1], nums[0] > nums[1],
2. 当 n > 1,假设命题对 n = k 成立。当 n = k + 1 的时候:
考虑 nums[0] 和 nums[1]。
若 nums[0] > nums[1],则 nums[0] 是一个峰,有解。
若 nums[0] < nums[1],则我们可以将问题的范围转化为 nums[1] 到 nums[n-1]。此时 nums[1] > nums[0], nums[n-1] > nums[n] 依然成立。由归纳假设,nums[1] 到 nums[n-1] 有解,即其存在峰。
同理可以证明 nums[n-1] 和 nums[n] 的情况。
因此综上我们得证原命题。
那么现在我们进行二分,k = (left + right) / 2
nums[k] > nums[k+1],那么我们的问题转化为 [left, k] 上的问题。
nums[k] < nums[k+1],问题转化为 [k+1, right] 上的问题。
因为二分总是会使范围缩小,当范围缩小到 1 时,峰值就找到了。
魔改一下官方题解 Java 的代码,通过了:
1 public int findPeakElement(int[] nums) { 2 int n = nums.length; 3 int left = 0, right = n - 1, ans = -1; 4 while (left < right) { 5 int mid = (left + right) / 2; 6 if (compare(nums, mid, mid + 1) > 0) { 7 right = mid; 8 } 9 else if (compare(nums, mid, mid + 1) < 0) { 10 left = mid + 1; 11 } 12 } 13 return left; 14 }