小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
题目
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到: 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2] 若旋转 7 次,则可以得到 [0,1,2,4,5,6,7] 注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。
给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
来源:力扣(LeetCode)
思路
1.旋转之后可以把数组分为两部分,一个是num[0]大的部分左部分,一个是比nums[0]小的部分右部分
2.两部分的数都是递增的,那么如果遇到不是递增的地方就是这两个部分的交界处
3.而对于需要寻找的最小值就是这个交界处,通过比较nums[0]和nums[mid]的值来判断当前的mid是在左半部分还是右半部分
-
如果在左半部分,则通过left = mid +1 //向右靠
-
如果在右半部分,则通过right = mid -1 //向左靠
if (nums[mid] > nums[mid + 1]) {
return nums[mid + 1];
}
if (nums[mid] < nums[mid - 1]) {
return nums[mid];
}
代码
class Solution {
public int findMin(int[] nums) {
int left = 0;
int right = nums.length - 1;
//没有发生旋转
if (nums[0] < nums[right]) return nums[0];
while (left < right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] > nums[mid + 1]) {
return nums[mid + 1];
}
if (nums[mid] < nums[mid - 1]) {
return nums[mid];
}
if (nums[mid] > nums[0]) { //说明在左边部分
left = mid + 1;
} else {
right = mid - 1;
}
}
return nums[left];
}
}