【算法】二分算法——寻找旋转排序数组中的最小值

简介: 【算法】二分算法——寻找旋转排序数组中的最小值

题解:寻找旋转排序数组中的最小值(二分算法)

1.题目

题目链接:LINK

2.暴力求解

思路:挨个便利,看哪里突然变小了就返回该数值即可。当然,如果没有变小的情况可以返回nums[0]位置。

class Solution {
public:
    //暴力求解思路
    int findMin(vector<int>& nums) 
    {
        int fornum = nums[0];
        for(size_t i = 1; i < nums.size(); i++)
        {
            if(nums[i] < fornum) return nums[i];
            fornum = nums[i];
        }
        return nums[0];
    }
};

3.二分算法

其实这个题目有鲜明的二段性

这里我们以D点作为分界值来区分:

参考代码如下:

class Solution {
public:
    //二分算法
    int findMin(vector<int>& nums) 
    {
        int left = 0, right = nums.size() - 1;
        int D = nums.size() - 1;
        while(left < right)
        {
            int mid = left + (right - left) / 2;
            if(nums[mid] <= nums[D]) right = mid;
            else left = mid + 1;
        }
        return nums[left];
    }
};

当然,这个题我们也可以用nums[0]来作为参考点区分两段数组。

如果mid >= A , left = mid;

如果mid < A , right = mid - 1;

特殊情况:

然后就可以写出这样的代码:

class Solution {
public:
    //二分算法
    int findMin(vector<int>& nums) 
    {
        int left = 0, right = nums.size() - 1;
        while(left < right)
        {
            int mid = left + (right - left) / 2;
            if(nums[mid] < nums[0]) right = mid;
            else left = mid + 1;
        }
        //特殊情况做处理
        // if(nums.size() >=2 && nums[left-1] < nums[left]) return nums[0];
        return nums[left];
    }
};

但是有个问题:就是上面数组,可能会出现这种情况:

也就是我们代码需要找的C点直接没有了,不存在了。实际上这种情况下答案要转换为我们对应的A点,但是你的代码是要的B点。

因此我们可以加上一条特殊判断就行:

class Solution {
public:
    //二分算法
    int findMin(vector<int>& nums) 
    {
        int left = 0, right = nums.size() - 1;
        while(left < right)
        {
            int mid = left + (right - left) / 2;
            if(nums[mid] < nums[0]) right = mid;
            else left = mid + 1;
        }
        //特殊情况做处理
        if(nums.size() >=2 && nums[left-1] < nums[left]) return nums[0];
        return nums[left];
    }
};

4.思考:为什么用A作为界点和用D作为界点不一样,一个需要特殊处理,另一个则不需要???

我们不妨就拿着那个报错的特殊用例来看,假设用A作分界点(用数组第一个值作为划分依据)和用D(用数组最后一个数字作为划分依据)作为分界点的方法都对下面这组数据进行求值:

我们发现两种方法有着不同的划分方式:

说白了,用数组第一个值作为划分依据的方法直接把我们要求的值划没了,但是另一种划分方法巧妙的把这种特殊情况归类到了我们的求值范围内。

换言之,用A作为界点只适用于下图两条线都存在的情况(如果不做特殊处理)

而用D点作为划分依据则适用于所有情况:

5.总结

这个题倒是不难,但是到底用哪个值作为界点值得我们思考。


EOF

相关文章
|
14天前
|
存储 人工智能 算法
C 408—《数据结构》算法题基础篇—数组(通俗易懂)
408考研——《数据结构》算法题基础篇之数组。(408算法题的入门)
58 23
|
4月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
58 0
|
4月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
71 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
4月前
|
存储 算法 定位技术
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
这篇文章主要介绍了稀疏数组和队列的概念、应用实例以及如何使用数组模拟队列和环形队列的实现方法。
50 0
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
|
6月前
|
存储 算法 Java
深入算法基础二分查找数组
文章深入学习了二分查找算法的基础,通过实战例子详细解释了算法的逻辑流程,强调了确定合法搜索边界的重要性,并提供了Java语言的代码实现。
深入算法基础二分查找数组
|
6月前
|
算法
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
|
6月前
|
算法
【算法】模拟算法——外观数组(medium)
【算法】模拟算法——外观数组(medium)
|
6月前
|
算法
【算法】前缀和——除自身以外数组的乘积
【算法】前缀和——除自身以外数组的乘积
|
6月前
|
算法
【算法】前缀和——寻找数组的中心下标
【算法】前缀和——寻找数组的中心下标
|
1天前
|
算法 数据安全/隐私保护 计算机视觉
基于FPGA的图像双线性插值算法verilog实现,包括tb测试文件和MATLAB辅助验证
本项目展示了256×256图像通过双线性插值放大至512×512的效果,无水印展示。使用Matlab 2022a和Vivado 2019.2开发,提供完整代码及详细中文注释、操作视频。核心程序实现图像缩放,并在Matlab中验证效果。双线性插值算法通过FPGA高效实现图像缩放,确保质量。

热门文章

最新文章