今日题目(剑指Offer系列)
剑指 Offer 11. 旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。 例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转, 该数组的最小值为1。
示例:
示例 1: 输入:[3,4,5,1,2] 输出:1 示例 2: 输入:[2,2,2,0,1] 输出:0
解题思路:
>本题目采用类似于二分查找的方法 >因为题目中说该数组为递增有序,经过旋转后可以分为两个有序数组 >我们首先想 >判断数组的中间值与最后一个值进行判断 >如果中间值大于最后一个值,说明较小的递增有序数组在右面,则low=mid+1 >而如果中间值小于最后一个值,说明较小的递增有序数组在左面,则high=mid >这里为什么不是mid-1呢?因为中间值小于最后一个值不能够说明mid不是最小值 >而上面中间值大于最后值,说明中间值肯定不是最小值,可以进行mid+1 >第三种情况就是二者相等,此时判断不出最小值在哪边,但是有一点可以确定 >中间值与最后值重复了,所以可以将high--, >而如果将low=mid,或者high=mid,会丢失很多值,有可能将最小值丢失掉, >high--,只会将这个重复值丢掉,重新进行第二轮判断
Python解法:
class Solution: def minArray(self, numbers: List[int]) -> int: low=0 high=len(numbers)-1 while low<high: mid=(low+high)//2 if numbers[mid]>numbers[high]: low=mid+1 elif numbers[mid]<numbers[high]: high=mid else: high-=1 return numbers[low]
Java解法:
class Solution { public int minArray(int[] numbers) { int low = 0; int high = numbers.length - 1; while (low < high) { int mid = (low + high) / 2; if (numbers[mid] > numbers[high]) { low = mid + 1; } else if (numbers[mid] < numbers[high]) { high = mid; } else { high -= 1; } } return numbers[low]; } }