153. 寻找旋转排序数组中的最小值【力扣】

题意理解

对一个数组旋转一部分元素,求数组中的最小值。

问题分析

找特征,如果旋转元素个数为0,那么最小数就是数组的第一个数字;如果个数不为0,那么最小元素藏在中间。旋没旋转可以通过判断首元素和尾元素大小判断。对于最小元素藏在中间的情况,使用二分法,最小元素左边的元素都比首元素大,右边的元素都比首元素小。判断mid是不是最小,可以通过特征邻接元素比大小来判断。

补充20200509:以上思路如果出现首尾中间三值相等无法正确处理。转换思路如下:

经过旋转后的数组分为两段,左边一段递增,右边一段递增,左边一段比右边一段都大。最小值的位置在右边一段的最前面。

low的变化范围包括左边一段+最小值;high的变化范围包括右边一段。

取中以后,如何移动low,high位置呢?将mid值和high值比较,如果比mid值大,说明在左边一段,将low设置为mid后一位,不是mid,因为low的范围可以包含最小值;如果比mid值小,说明在右边一段,将high设置为mid位,不是mid-1,因为high的范围不能超过右边一段。这样直到low==high,这时候的落点一定是最小值。

其他

同类型题目:力扣

20211024:有点难

链接

class Solution {
public:
    int findMin(vector<int>& nums) {
        int len=nums.size();
        if(len==0) return -1;
        if(len==1) return nums[0];
        
        
        if(nums[0]<nums[len-1]) {    //没有旋转元素的情况
            return nums[0];
        }
        else {
            int low=0, high=len-1;    
            while(low<high) {    //二分查找
                int mid=(low+high)/2;
                if(nums[mid]>nums[mid+1]) return nums[mid+1]; //最小值判断
                if(nums[mid-1]>nums[mid]) return nums[mid];    //最小值判断
                if(nums[mid]>nums[0]) {    //缩小范围
                    low=mid+1;
                }
                else {    //缩小范围
                    high=mid-1;
                }
            }
        }
        return -1;
    }
};

0509:

    int minArray(vector<int>& numbers) {
        int low = 0;    //小端范围在最小值及最小值左边
        int high = numbers.size() - 1;  //大端范围仅在最小值及最小值右边
        while (low < high) {
            int mid = low + (high - low) / 2;
            if (numbers[mid] < numbers[high]) {
                high = mid;
            }
            else if (numbers[mid] > numbers[high]){
                low = mid + 1;
            }
            else {
                high --;    //关键代码
            }
        }
        return numbers[low];
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值