153. 寻找旋转排序数组中的最小值

注意为什么不用nums[mid]和nums[l]比较大小来识别最小值的位置,因为在[1,2,3,4]这个case下该策略就不管用了,所以比较点使用nums[r]。可以这样理解,排序数组[1,2,3,4,5,6]旋转后[4,5,6,1,2,3],将数组分成了两个数组,前面一个数组[4,5,6]的元素都大于后面一个数组[1,2,3]的元素,要寻找的就是后面一个数组的第一个元素:
- 当nums[mid]<nums[r]时,说明mid在后面一个数组中,此时
r = mid; - 当nums[mid]>nums[r]时,说明mid在第一数组里,此时
l = mid + 1 当
l==r时找到最小元素迭代结束class Solution {public int findMin(int[] nums) {if (nums == null || nums.length == 0) throw new IllegalArgumentException();int l = 0, r = nums.length - 1;while (l < r) {int mid = l + (r - l) / 2;if (nums[mid] > nums[r]) {l = mid + 1;} else {r = mid;}}return nums[l];}}
154. 寻找旋转排序数组中的最小值 II

思路:和153题类似,主要考虑存在相等元素的情况,这里是个难点。class Solution { public int minArray(int[] numbers) { if(numbers == null || numbers.length == 0) throw new IllegalArgumentException(); if (numbers[0] < numbers[numbers.length - 1]) return numbers[0]; int l = 0, r = numbers.length - 1; while (l < r) { int mid = l + (r - l) / 2; if (numbers[mid] < numbers[r]) { r = mid; } else if (numbers[mid] > numbers[r]){ l = mid + 1; } else { r = r - 1; } } return numbers[l]; } }300. 最长递增子序列
方法1:动态规划
方法2:贪心+二分查找33. 搜索旋转排序数组

class Solution { //[4,5,6,7,0,1,2], public int search(int[] nums, int target) { int minIndex = findMin(nums); if (minIndex == 0) { return binarySearch(nums, 0, nums.length - 1, target); } int left = binarySearch(nums, 0, minIndex - 1, target); int right = binarySearch(nums, minIndex, nums.length - 1, target); if (left == -1 && right == -1) return -1; return left == -1 ? right : left; } private int binarySearch(int[] nums, int l, int r, int target) { while (l <= r) { int mid = l + (r - l) / 2; if (nums[mid] < target) { l = mid + 1; } else if (nums[mid] > target) { r = mid - 1; } else { return mid; } } return -1; } private int findMin(int[] nums) { int l = 0, r = nums.length - 1; while (l < r) { int mid = l + (r - l) / 2; if (nums[mid] > nums[r]) { l = mid + 1; } else { r = mid; } } return r; } }
