C语言练习题 寻找最小值

之前博客主要参考比特的免费课程和一部分百度、MSDN等资料。

后面一阶段会进行C语言练习,先在牛客网刷一点简单的题目。

描述

有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。

数据范围:1≤n≤10000,数组中任意元素的值: 0≤val≤10000

要求:空间复杂度:O(1) ,时间复杂度:O(logn)

空间复杂度O(1):算法在执行过程中,无论输入数据规模如何变化,所占用的额外空间保持恒定,即不随输入数据规模的增加而增加。

时间复杂度O(logn):算法的运行时间与输入规模n的对数成正比。

遍历查找:

//遍历查找
int min(int* nums, int numsLen) //函数所需参数为数组地址和数组元素数量
{
    int i = 0;
    int tmp = nums[0];          //创建临时变量,存储最小值,初始数值为首元素的值
    for (i = 0; i < numsLen; i++)   //遍历查找,遇到更小数值则存入tmp变量中
    {
        if (nums[i] < tmp)
        {
            tmp = nums[i];
        }
    }
    return tmp;         //查找结束后,返回tmp,即为最小值。
}
//遍历查找编程很简单,但是如果遇到数据量庞大,则会非常耗时。不符合时间复杂度O(logn)

遍历查找的程序写起来很简单,但是当数据量很庞大时,它所花费的时间和资源也会非常巨大。

二分查找:

//二分查找
//二分查找就需要考虑有重复数值的情况
int min(int* nums, int numsLen)
{
    if (numsLen == 1)       //如果数组只有一个数,直接返回该数
        return nums[0];
    int left = 0;               //定义左边元素坐标
    int right = numsLen - 1;    //定义右边元素坐标
    int mid = 0;                //定义中间元素坐标
    while (left < right)
    {
        mid = (left + right) / 2;   //中间元素坐标为 左右两边中间,除不尽时靠近左边
        if (nums[mid] < nums[right])    //如果中间值小于右边值,则最小值一定坐标在 [left,mid]之间
            right = mid;                //将右边界坐标改为mid
        else if (nums[mid] > nums[right])   //如果中间值大于右边值,则最小值一定在[mid+1,right]之间
            left = mid + 1;                 //将左边界改为 mid+1 。防止 mid = (left + right) / 2 除不尽陷入死循环
        else
        {
                right--;                //如果中间值等于右边值,则最小值可能在任何地方,此时采用遍历的思路逐个对比
        }
        if (left == right)      //如果left = mid+1 后 left = right 了,则需要及时更新,防止mid除不尽输出nums[left]
            mid = left;
    }
    return nums[mid];       //找出最小值坐标,返回其在数组中的值。
}

当中间值等于右边值时,最小值可能是下面任何一个1变成0(除中间值),所以要通过遍历的方式找到它的坐标,然后再按照二分法的节奏快速定位。

11111111111111111111

二分法虽然程序写起来麻烦一点,但数据庞大时,可以节省时间。

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在这个实验中,有三个源程序被引用。第一个源程序是用指针变量实现数的比较,输入两个整数,并使其从大到小输出。\[1\]第二个源程序是用指针法输入12个数,然后按每行4个数输出。\[2\]第三个源程序是用函数实现数的交换,输入两个整数,并使其从大到小输出。\[3\] 在第一个源程序中,通过指针变量p1和p2来比较两个整数的大小,并使用指针变量p来交换两个整数的值。最后输出a和b的值以及最大值和最小值。\[1\] 在第二个源程序中,使用指针变量p来遍历数组a,并按每行4个数的格式输出数组中的元素。\[2\] 在第三个源程序中,使用函数as来实现两个整数的交换。通过指针变量p1和p2来传递两个整数的地址,并在函数内部交换它们的值。最后输出a和b的值以及最大值和最小值。\[3\] 这些实验都是为了练习和理解C语言中指针的使用。通过这些实验,可以加深对指针的理解,并掌握指针在程序中的应用。 #### 引用[.reference_title] - *1* *2* *3* [C语言实验十一 指针(一)](https://blog.csdn.net/qq_64314976/article/details/126123133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值