目录
[1. 山峰数组的峰顶](#1. 山峰数组的峰顶)
[2. 寻找峰值](#2. 寻找峰值)
[3. 搜索旋转排序数组中的最小值](#3. 搜索旋转排序数组中的最小值)
[4. 0~n-1 中缺失的数字](#4. 0~n-1 中缺失的数字)
1. 山峰数组的峰顶
题目链接 :852. 山脉数组的峰顶索引
解题思路:
使用二分查找,找到满足
arr[mid] > arr[mid - 1]的最后一个位置。如果
arr[mid] > arr[mid - 1],说明还在上升阶段,答案在[mid, right]。否则说明已经过了峰顶,答案在
[left, mid - 1]。最后返回
left。
Java 代码:
java
class Solution {
public int peakIndexInMountainArray(int[] arr) {
int left = 1, right = arr.length - 2;
while (left < right) {
int mid = left + (right - left + 1) / 2;
if (arr[mid] > arr[mid - 1]) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
}
2. 寻找峰值
题目链接 :162. 寻找峰值
解题思路:
利用"任意相邻元素不相等"和"两端视为负无穷"的条件。
比较
arr[mid]与arr[mid + 1]:
如果
arr[mid] < arr[mid + 1],说明右侧存在峰值,left = mid + 1。否则说明左侧存在峰值,
right = mid。最终返回
left。
Java 代码:
java
class Solution {
public int findPeakElement(int[] nums) {
int left = 0, right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] < nums[mid + 1]) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
}
3. 搜索旋转排序数组中的最小值
题目链接 :153. 寻找旋转排序数组中的最小值
解题思路:
将数组最后一个元素
x作为参照点。比较
nums[mid]与x:
如果
nums[mid] > x,说明mid在旋转点左侧,最小值在右侧,left = mid + 1。否则说明
mid在旋转点右侧或就是最小值,right = mid。最后返回
nums[left]。
Java 代码:
java
class Solution {
public int findMin(int[] nums) {
int left = 0, right = nums.length - 1;
int x = nums[right];
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] > x) {
left = mid + 1;
} else {
right = mid;
}
}
return nums[left];
}
}
4. 0~n-1 中缺失的数字
题目链接 :剑指 Offer 53-II. 0~n-1中缺失的数字
解题思路:
在缺失位置之前,
nums[i] == i;之后,nums[i] != i。比较
nums[mid]与mid:
如果
nums[mid] == mid,说明缺失位置在右侧,left = mid + 1。否则说明缺失位置在左侧或当前位置,
right = mid。最后判断
nums[left]是否等于left,决定返回left + 1还是left。
Java 代码:
java
class Solution {
public int missingNumber(int[] nums) {
int left = 0, right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] == mid) {
left = mid + 1;
} else {
right = mid;
}
}
return nums[left] == left ? left + 1 : left;
}
}