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

剑指 Offer 11. 旋转数组的最小数字 - 力扣(LeetCode) (leetcode-cn.com)

首先放上运行结果

思路

如果数列确实经过了旋转且无重复数字,那么它满足如下特点:

1. 从最小元素到数列末尾元素,均小于首元素

2. 从首元素到最大元素,均大于等于首元素

根据这两点,我们可以进行二分查找,设首元素所在位置为front,末尾元素所在位置为back,中间元素所在位置为mid。if numbers[mid] < numbers[front], then back = mid; if numbers[mid] > numbers[front], then front = mid;如此进行,直到back == front + 1,此时front位置为最大元素,back位置为最小元素。

如果数列并未经过旋转,那么整个数列是递增的,首元素一定小于末尾元素,此时直接返回首元素即可。

如果数列中有大量重复元素,比如numbers[mid] == numbers[front]的情况,此时最小元素可能出现在mid左边,也可能出现在mid右边,我们无法确定它的位置,只能暴力查找。

代码

class Solution {
public:
    int minArray(vector<int>& numbers) {
        int front = 0, back = numbers.size() - 1, halfsize, mid;
        if(numbers[front] < numbers[back]) return numbers[front];

        while (halfsize = (back - front) / 2) {
            mid = front + halfsize;

            if (numbers[mid] == numbers[front]) {
                int _min = numbers[front];
                for(int i = front + 1; i <= back; ++i) numbers[i] < _min ? _min = numbers[i] : NULL;
                return _min;
            }

            numbers[mid] > numbers[front] ? front = mid : back = mid;
        }
        return numbers[back];
    }
};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值