Leetcode签到题:旋转数组的最小数字(一只菜鸡的刷题路)

题目

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组
[3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。

题目链接:
剑指 Offer 11. 旋转数组的最小数字
来源:力扣(LeetCode)

涉及的知识点:二分查找


求解思路

题目所给旋转数组的特点:
设数组的最后一个元素为x,该数组最小的元素为min。原数组中,min左边的所有元素均大于等于x,min右边的所有元素均小于等于x。 根据这一特点,我们可以得出,利用二分查找,一定可以找到min。


二分查找
本题,我们将二分查找过程中的左边界设为left,右边界设为right,区间的中点设为mid。其中,初始化left为0,right为numbers.length-1。数组的最小值min一定在该区间内。

在对区间进行更新前,我们需要计算区间的中点,接着判断numbers[mid]numbers[right]的大小关系,共有三种情况,分别进行不同的区间更新操作,直至找到最小值:

  1. numbers[mid] < numbers[right]
    则令right = mid
  2. numbers[mid] > numbers[right]
    则令left = mid+1
    【备注:mid+1保证了左边界不会因为原地踏步而造成死循环】
  3. numbers[mid] == numbers[right]
    相等情况,我们无法保证min到底是在mid的左边还是右边,则进行right--操作

最终,当left不再小于right时,说明我们找到了最小值,并返回最小值。


AC代码

class Solution {
    public int minArray(int[] numbers) {
    	int left = 0;
    	int right = numbers.length-1;
    	while(left < right) {
    		int mid = left+(right-left)/2;
    		if(numbers[mid] < numbers[right]) {
    			right = mid;
    		}else if(numbers[mid] > numbers[right]){
    			left = mid+1;
    		}else {
    			right--;
    		}
    	}
    	return numbers[left];
    }
}

细节说明
这里mid的更新代码为int mid = left+(right-left)/2,可以避免(left+right)/2leftright的数值太大,造成溢出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值