C 语言每日一题——旋转数组的最小数字

一、题目内容

提供一下该OJ题的链接:旋转数组的最小数字_牛客题霸_牛客网 (nowcoder.com)

二、题目分析

通过示例1可知,我们写代码的目的是在数组中找到一个最大值,并且返回来;

我们很容易的会想到创建一个变量:int min = 0; 然后遍历整个数组,依次比较把一个最小值用该变量接收;但是时间复杂度是O(n),空间复杂度是O(1),这很显然不符合题目时间复杂度O(logn)的要求。

通过O(logn),这个要求,我们由果索因,会想到之前我们经常打招呼的二分查找法,其时间复杂度符合O(logn);但是二分查找的前提是:需要数组的有序的;

我们如果对它进行排序的话,那最快的排序的时间复杂度至少是O(nlogn),显然我们要先排序是不可行的。

我们在仔细回阅问题的描述;发现这个旋转数组也有他的特殊之处:

1.该数组有两个子数组是有序的。且该数组的最小值一定在数组的前一个字数组升序边界;

2.该数组的最后一个元素很大概率不属于我们要找的元素;

于是我们得出了一个类似于二分法(也是用双指针),但不同于二分法什么时候折半区间的考虑

根据对上图的理解:我们就可以知道,这题中的二分法,与之前用的二分法,差别就在于判断条件。

那有人会问,若下标mid所指向的值 = 下标right所指向的值,该怎么办?

right-1;缩小范围;。

三、完整代码

复制代码
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param nums int整型一维数组 
 * @param numsLen int nums数组长度
 * @return int整型
 */
int minNumberInRotateArray(int* nums, int numsLen ) 
{
    int lift  = 0;
    int right = numsLen-1;
     //4 5 6 7 8 9 1 2 3
     //8 9 1 2 3
     //8 9 1
     //1
     while(lift<right)
    {
         int mid   = (lift+right)/2;
    if(nums[mid]>nums[right])
    {
        //前边的一半区间可以抛弃;
        lift = mid+1;
    }
    else if(nums[mid]<nums[right])
    {
        //后别的一半区间可以抛弃(不包括mid);
        right = mid;
    }
    else
    {
        //往前面走一位;
        right -= 1;
    }
    }
    return nums[lift];
}
相关推荐
wljun73925 分钟前
六、OrcaSlicer 切片之区域
算法·切片软件 orcaslicer
superman超哥29 分钟前
仓颉Option类型的空安全处理深度解析
c语言·开发语言·c++·python·仓颉
2401_8414956430 分钟前
【LeetCode刷题】跳跃游戏Ⅱ
数据结构·python·算法·leetcode·数组·贪心策略·跳跃游戏
leaves falling31 分钟前
动态规划讲解
算法·动态规划
钓鱼的肝1 小时前
GESP系列(3级)小杨的储蓄
开发语言·数据结构·c++·笔记·算法·gesp
MicroTech20251 小时前
MLGO微算法科技推出人工智能与量子计算融合新成果:基于QLSS与LCHS的量子DPM算法技术
人工智能·科技·算法
AndrewHZ1 小时前
【图像处理基石】[特殊字符]圣诞特辑:10+经典图像处理算法,让你的图片充满节日氛围感!
图像处理·人工智能·opencv·算法·计算机视觉·stable diffusion·节日氛围感
艾醒1 小时前
大模型原理剖析——矩阵吸收优化:LLM推理加速的核心原理与实践
算法
Trouvaille ~1 小时前
【Linux】库制作与原理(二):ELF格式与静态链接原理
linux·运维·c语言·操作系统·动静态库·静态链接·elf文件
艾醒1 小时前
大模型原理剖析——多头并行 + 潜变量协同:原理、应用与部署优化
算法