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];
}
相关推荐
WHS-_-20221 小时前
A Density Clustering-Based CFAR Algorithm for Ship Detection in SAR Images
算法·5g
Kiri霧3 小时前
Linux下的Rust 与 C 的互操作性解析
c语言·开发语言·rust
Miraitowa_cheems4 小时前
LeetCode算法日记 - Day 68: 猜数字大小II、矩阵中的最长递增路径
数据结构·算法·leetcode·职场和发展·贪心算法·矩阵·深度优先
希赛网4 小时前
软考软件设计师常考知识点:(三)数据结构
数据结构·二叉树·字符串·软考·软件设计师·线性表
迎風吹頭髮4 小时前
UNIX下C语言编程与实践62-UNIX UDP 编程:socket、bind、sendto、recvfrom 函数的使用
c语言·单片机·unix
灵感__idea6 小时前
Hello 算法:让前端人真正理解算法
前端·javascript·算法
学习2年半6 小时前
小米笔试题:一元一次方程求解
算法
MATLAB代码顾问6 小时前
MATLAB绘制多种混沌系统
人工智能·算法·matlab
极客BIM工作室7 小时前
演化搜索与群集智能:五种经典算法探秘
人工智能·算法·机器学习
qq_574656257 小时前
java-代码随想录第66天|Floyd 算法、A * 算法精讲 (A star算法)
java·算法·leetcode·图论