一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第20天,点击查看活动详情。
前言
力扣第153题 寻找旋转排序数组中的最小值
如下所示:
一、思路
我们注意题目中提示信息:数组中所有整数都不相同,这意味着我们无需考虑翻转的地方是否发生在相同元素的地方。
我们可以将这个数组想象成一个分开的折线图,如下所示:
既然要找到 旋转数组的最小值
,我们就需要先知道 旋转的位置
,也就是说找到新数组中第二次升序的起始位置,如下图所示:
那如何快速找到这个点呢?我们很明显可以想到 二分法
。然后考虑以下几种情况
mid:数组的中间下面
mid
落在第一段升序上,即nums[mid] > nums[right]
此时丢弃左边即可,如下图所示:
mid
落在第二段升序上,即
此时丢弃右边即可,如下图:nums[mid] < nums[right]
经过不断的丢弃左右区间,最终 left == right
,下标指向旋转起始的元素。
举个例子
此处以示例中的 nums = {4,5,6,7,0,1,2}
作为例子
- 初始化变量:
left = 0, right = 6
mid = 3
,nums[mid] > nums[right]
。丢弃左边left = mid + 1 = 4
mid = 5
,nums[mid] < nums[right]
。丢弃右边right = mid = 5
mid = 4
,nums[mid] < nums[right]
。丢弃右边right = mid = 4
- 此时
left = right = 4
,返回nums[4]
的值0
即可
二、实现
实现代码
实现代码中为了避免死循环,在丢弃左部分时需要丢弃包括自身的元素,即 left = mid + 1
public int findMin(int[] nums) {
int left = 0;
int right = nums.length-1;
while (left < right){
int mid = (left + right)/2;
if (nums[mid] < nums[right]){
right = mid;
}else {
left = mid + 1;
}
}
return nums[left];
}
测试代码
public static void main(String[] args) {
int[] nums = {4,5,6,7,0,1,2};
new Number153().findMin(nums);
}
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥
如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~