AcWing 22. 旋转数组的最小数字(二分法)

本文介绍了一种高效算法,通过二分法在旋转数组中查找最小元素,特别适用于元素可能重复的情况。文章详细解析了算法思路,并提供了具体实现代码。

这个问题投机的做法就是将数组排序然后输出最小元素。但这种做法并不推荐,原因就不解释了。

这道题最好的做法是使用二分法。在解决这个问题前,先假设数组是一个元素互异且递增的数组。那么其中一定满足nums[n]>nums[0]。当此数组发生了旋转后,则必有nums[n]<nums[0]。此时,我们可以利用这一条件结合二分法来查找最小元素。如果nums[mid]<nums[0],则说明最小元素在mid左侧,否则说明在右侧。以此就可以逐步缩小区间直至找到最小元素。

不过,题目说明了数字中可能存在重复元素。那么有没有必要对所有的元素进行去重操作呢?答案是:如果nums[0]==nums[n]则需要对数组尾端等于nums[0]的元素进行去重操作,否则的话不需要。也就是说只要保证nums[n]<nums[0]就可以了。具体的实例可以参考题解

具体代码如下:

class Solution {
public:
    int findMin(vector<int>& nums) {
        if(nums.empty()) return -1;
        int n = nums.size() - 1;
        while(n > 0 && nums[n] == nums[0]) n--; //数组尾部去重
        if(nums[n] >= nums[0]) return nums[0]; //数组是单调的,没有发生旋转
        int lo = 0, hi = n;
        while(lo < hi){
            int mid = (lo + hi) >> 1;
            if(nums[mid] < nums[0]) hi = mid;
            else lo = mid + 1;
        }
        return nums[hi];
    }
};

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值