题目描述 题目分析 给定的数组是一个已经在某个未知点经过旋转的的,且在旋转之前是排好序的数组那么这个数组就是有特性的: 整个数组可以大致分为两块,左和右,以旋转点进行分割,可以得到两个升序排序的子数组且左数组的数字都会比右数组的数字要大,因为旋转之前是升序排序的 题目要求最后获得数组中的最小值 解法分析 最暴力的方法就是全部遍历一遍,找到最小值,时间复杂度为O(N)因为数组已经是排好序的,我们可以用二分法寻找最小值,但是判断的条件会不一样现在假设左边的升序排序数组为 A ,右边的升序排序数组为 B 代码 class Solution { public int findMin(int[] nums) { if (nums.length == 1) return nums[0]; int left = 0; int right = nums.length-1; // 尾部比头部大,那就是已经排好序并且未旋转的 if(nums[0] < nums[right]) return nums[0]; while(left <= right){ int mid = (right+left)/2; // 找到旋转点 if(nums[mid] > nums[mid+1]) return nums[mid+1]; if(nums[mid-1] > nums[mid]) return nums[mid]; // 如果中间点比头元素大,就说明在左边,那就往右边找 // 如果中间点比头元素小,就说明在右边,那就往左边去找 if(nums[mid] > nums[0]){ left = mid+1; } else { right = mid-1; } } return -1; } } 但是这样写太啰嗦了,来个精简版 public int findMin(int[] nums) { // 定义两个指针 int left = 0, right = nums.length - 1; // 开始查找,直到两指针相遇 while (left < right) { // 定义中间指针 int middle = (left + right) / 2; // 如果中间值比右值小,因为数组是升序排序的数组 if (nums[middle] < nums[right]) { // middle可能是最小值 right = middle; } else { // 如果中间值比右值大或相等 // middle肯定不是最小值 left = middle + 1; } } return nums[left]; }