一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情。
前言
力扣第154题 寻找旋转排序数组中的最小值 II 如下所示:
一、思路
这一题与前面一题力扣第153题-寻找旋转排序数组中的最小值非常的相似,唯一不同的就是:这一题的数组中含有重复的元素。
题目很长,我们可以简单的总结一下,按照下面三步分解:
-
有一个升序数组
nums = [a0, a1, ..., an] -
经过
m次旋转后变为了nums = [am, a(m+1), a(m+2) ..., an, a0, a1, a2, ..., a(m-1)] -
找到原数组中的第一个元素
a0
为了更进一步的理解题目,我们可以将题目以图形的形式表示出来。我们假设一个经过旋转过后,有重复元素的数组如下图所述:
我们的目的就是找到未旋转前的第一个元素,如下图所示:
至于具体实现的方式,还是与上一题保持一致,都使用 二分法。不过值得注意的是,需要特殊处理中间元素与有边界值相等的情况。当 nums[mid] == nums[right] 时,我们可以丢弃右边界,因为原数组的第一个元素一定在旋转过后的数组的左侧。就像下面这种情况,我们要选择丢弃右边界。
二、实现
实现代码
实现代码与思路中保持一致。所谓丢弃右边界的元素就是让右边界的下标减一即可。
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 if (nums[mid] > nums[right]){
left = mid + 1;
} else {
right--;
}
}
return nums[left];
}
测试代码
public static void main(String[] args) {
int[] nums = {5, 6, 7, 0, 1, 4, 4};
new Number154().findMin(nums);
}
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥
如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~