153. 寻找旋转排序数组中的最小值
和之前一道题思路一致,每次判断是左边有序还是右边有序,左边有序将左边界加入最小值,否则将中间值加入最小值。
public int findMin(int[] nums) {
int re = Integer.MAX_VALUE;
int left = 0, right = nums.length - 1;
while (left <= right){
int mid = (left + right) / 2;
if (nums[left] <= nums[mid]){
re = Math.min(re, nums[left]);
left = mid + 1;
} else {
re = Math.min(re, nums[mid]);
right = mid - 1;
}
}
return re;
}
//优化
public int findMin1(int[] nums) {
int low = 0;
int high = nums.length - 1;
while (low < high) {
int mid = low + (high - low) / 2;
if (nums[mid] < nums[high]) {
high = mid;
} else {
low = mid + 1;
}
}
return nums[low];
}
154.寻找旋转排序数组中的最小值 II
比之前多了一个numbers[m] == numbers[j]的判断
public int minArray(int[] numbers) {
int i = 0, j = numbers.length - 1;
while (i < j) {
int m = (i + j) / 2;
if (numbers[m] > numbers[j]) i = m + 1;
else if (numbers[m] < numbers[j]) j = m;
else j--;
}
return numbers[i];
}
162. 寻找峰值
O(logN)一般考虑二分搜索。有如下规律:
规律一:如果nums[i] > nums[i+1],则在i之前一定存在峰值元素
规律二:如果nums[i] < nums[i+1],则在i+1之后一定存在峰值元素
public int findPeakElement(int[] nums) {
int left = 0, right = nums.length - 1;
while (left < right){ //找到left=right的最后一个数,一定是峰值
int mid = (left + right) / 2;
if (nums[mid] > nums[mid + 1]) right = mid; //如果nums[i] > nums[i+1],则在i之前一定存在峰值元素
else left = mid + 1; //如果nums[i] < nums[i+1],则在i+1之后一定存在峰值元素
}
return left;
}