题目:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。
注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。
示例 1:
输入:numbers = [3,4,5,1,2]
输出:1
示例 2:
输入:numbers = [2,2,2,0,1]
输出:0
提示:
- n == numbers.length
- 1 <= n <= 5000
- -5000 <= numbers[i] <= 5000
numbers 原来是一个升序排序的数组,并进行了 1 至 n 次旋转
注意:本题与 力扣 154 题 相同:
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
参考 liweiwei1419的题解 ,感谢老师!
旋转数组的特点:
- 多次旋转相当于一次旋转;
- 旋转后的数组一分为二,一定为两段有序数组;
- 数组中最大值喝最小值一定是相邻的:如果最大值右边存在值,那一定是最小值;
- 如果两个数是上升趋势,那么两个数之间的数一定是上升的。
要满足【左边】小于【中间】,那么【左边】到【中间】的所有数字就都一定是全部属于连续上升趋势的,否则就不是一个旋转有序数组。
【中间值】与【左边】相比较? 还是【右边】,前提是比较的两者是连续上升的趋势
1.如果中间值与左边相比较,会存在以下两种情况:假设一共7个数
①[3,4,5,6,7,1,2],中间值为6,最小值在右边;
②[1,2,3,4,5,6,7],中间值为4,最小值在左边;
2.如果中间值与右边相比较,会存在以下三种情况:假设一共7个数
①[6,7,1,2,3,4,5],中间值为2,最小值在左边;
②[1,2,3,4,5,6,7],中间值为4,最小值在左边;
③[5,6,7,1,2,3,4],中间值为1也为最小值。
综上最好比较:【中间值】与【右边】
还有一种特殊情况:【中间值】等于【右边】
比如:[2,2,1,2,2,2,2],[2,2,2,2,1,2,2],中间值为2,就需要一步一步去掉右边值。
代码:
1 class Solution { 2 public int minArray(int[] numbers) { 3 int n = numbers.length; 4 if (n == 1) return numbers[0]; 5 int left = 0, right = n-1; 6 while (left < right){ 7 int mid = left + (right - left) / 2; 8 //mid不可能为最小值,下一轮搜索区间为[mid+1,right] 9 if (numbers[mid] > numbers[right]){ 10 left = mid + 1; 11 }else if (numbers[mid] < numbers[right]){ 12 //mid有可能就是最小值,下一轮搜索区间为[left,mid] 13 right = mid; 14 }else{ 15 //中间值与右边值相等,只能去掉右边值,下一轮搜索区间为[left,mid] 16 right--; 17 } 18 } 19 //循环结束使,right == left,一定有答案 20 return numbers[left]; 21 } 22 }标签:right,Java,mid,最小值,offer11,numbers,数组,left From: https://www.cnblogs.com/liu-myu/p/17264549.html