1 题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2 解题思路
参考大佬的题解,写的超级有条理还特别好理解:面试题11. 旋转数组的最小数字(二分法,清晰图解)
- 解题方法: 二分法
如下图所示,寻找旋转数组的最小元素即为寻找 右排序数组 的首个元素 numbers[x] ,称x 为 旋转点 。
排序数组的查找问题首先考虑使用 二分法 解决,其可将遍历法的线性级别 时间复杂度降低至 对数级别
。
作者:jyd
链接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/solution/mian-shi-ti-11-xuan-zhuan-shu-zu-de-zui-xiao-shu-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
3 解决代码
- 解题方法: 二分法《Java代码》
class Solution {
public int minArray(int[] numbers) {
int i = 0;
int j = numbers.length - 1;
while(i < j){
int m = (i + j) /2;
//当 numbers[m] > numbers[j]时: m 一定在 左排序数组 中,
//即旋转点 x 一定在 [m+1,j] 闭区间内,因此执行 i=m+1;
if(numbers[m] > numbers[j]){
i = m + 1;
}
//当 numbers[m] < numbers[j]时: m 一定在 左排序数组 中,
//即旋转点 x 一定在 [i,m] 闭区间内,因此执行 j = m;
else if(numbers[m] < numbers[j]){
j = m;
}
//当 numbers[m] == numbers[j] 时: 无法判断 m 在哪个排序数组中,
//即无法判断旋转点 x 在 [i,m] 还是 [m+1,j] 区间中。解决方案: 执行 j=j−1 缩小判断范围
else{
j= j - 1;
}
}
//当 i=j 时跳出二分循环,并返回 numbers[i] 即可。
return numbers[i];
}
}
- 解题方法: 二分法《python3代码》
class Solution:
def minArray(self, numbers: List[int]) -> int:
i = 0
j = len(numbers )- 1
while i < j:
m = (i + j) //2
if numbers[m] > numbers[j]:
i = m + 1
elif numbers[m] < numbers[j]:
j = m
else:
j = j - 1
return numbers[i]