剑指 Offer 11. 旋转数组的最小数字

在这里插入图片描述
https://leetcode.cn/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/

解法一
暴力法,直接遍历一遍数组,找出其中的最大值即可

class Solution {
    public int minArray(int[] numbers) {
        int min=Integer.MAX_VALUE;
        for(int number:numbers){
            if(number<min){
                min=number;
            }
        }
        return min;
    }
}
//O(n)
//O(1)
class Solution {
public:
    int minArray(vector<int>& numbers) {
        int min=INT_MAX;
        for(int num:numbers){
            if(num<min){
                min=num;
            }
        }
        return min;
    }
};
//O(n)
//O(1)
class Solution:
    def minArray(self, numbers: List[int]) -> int:
        min=10000
        for num in numbers:
            if num<min:
                min=num
        return min

解法二: 二分查找

对于旋转后的数字,虽然数组整体不是有序的,但是数组的分为两部分,这两部分一定是各自有序的,以numbers = [3,4,5,1,2]为例,3 4 5是升序的,1 2是升序的,即数组分为两部分有序,分别称为左半部分有序和右边部分有序, 最小的数字是右半部分的第一个数字

最右边的数字一定属于右半部分有序,将最右边的元素nums[r]和中间元素num[mid]进行比较,分为以下3种情况:

  1. nums[r]<nums[mid]: mid属于左半部分有序,最小数字属于区间[mid+1,r] mid不可能是最小数字,因此区间不包含mid
  2. nums[r]>nums[mid]: mid属于右半部分有序,最小数字属于区间[left,mid] mid可能是最小数字,因此区间包含mid
  3. nums[r]==nums[mid]: 由于数组中存在重复元素, 此时不直接返回,而是缩小右边界

这里不和nums[i]进行比较的原因是因为最开始的最左边的元素nums[i]并不能确定其属于左半部分有序数组还是右半部分有序数组

class Solution {
    public int minArray(int[] numbers) {
        int left=0,right=numbers.length-1;
        while(left<right){
            int mid=left+(right-left)/2;
            if(numbers[mid]>numbers[right]){
                left=mid+1;
            }else if(numbers[mid]<numbers[right]){
                right=mid;
            }else if(numbers[mid]==numbers[right]){
                right--;
            }
        }
        return numbers[left];
    }
}
//O(logn)
//O(1)
class Solution {
public:
    int minArray(vector<int>& numbers) {
        int l=0,r=numbers.size()-1;
        while(l<r){
            int m=l+(r-l)/2;
            if(numbers[m]>numbers[r]){
                l=m+1;
            }else if(numbers[m]<numbers[r]){
                r=m;
            }else if(numbers[m]==numbers[r]){
                r--;
            }
        }
        return numbers[l];
    }
};
class Solution:
    def minArray(self, numbers: List[int]) -> int:
        left=0
        right=len(numbers)-1
        while left<right:
            mid=left+(right-left)//2
            if numbers[mid]>numbers[right]:
                left=mid+1
            elif numbers[mid]<numbers[right]:
                right=mid
            elif numbers[mid]==numbers[right]:
                right-=1
        return numbers[left]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodePanda@GPF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值