算法复杂度分析

news/2024/11/7 12:43:29/

目录

一、计算资源

1、第十三届蓝桥杯 Python 组题目的时空限制汇总

2、Python 与 C/C++ 、Java 的限制对比

3、时间和空间限制

4、测量代码的运行时间

二、算法定义

1、计算复杂度

2、有哪些复杂度

三、算法评估 

1、分类

2、易解问题——难解问题:用多项式时间来区分

3、多项式函数与指数函数的增长对比

4、问题规模和可用算法(个人认为超级重要)

5、选择解题方法

6、例题举例

(1)暴力法(可拿部分的分)

(2)前缀和 (AC)


一、计算资源

  • 程序运行时需要的资源有两种
  • 时间:程序运行需要的时间
  • 空间:程序运行需要的存储空间
  • 资源是有限的

1、第十三届蓝桥杯 Python 组题目的时空限制汇总

2、Python 与 C/C++ 、Java 的限制对比

3、时间和空间限制

  • 程序必须在限定的时间和空间内运行结束。
  • 问题的“有效”解决,不仅在于能否得到正确答案,更重要的是能在合理的时间和空间内给出答案。 
  • 程序运行的时间:时间复杂度
  • 程序运行的空间:空间复杂度
  • O(n*m) 和 O(n*n*m):就是时间复杂度
  • 符号 O 表示复杂度, O(n*m) 可以粗略地理解为运行次数是 n*m
  • O(n*n*m) 比 O(n*m) 运行时间大 n 倍。

4、测量代码的运行时间

如何衡量代码运行的时间?在代码中打印运行时间,可以得到一个直观的认识。

下面代码只有一个 for 语句,代码对 k 进行累加,最后打印循环累加的运行时间。

(1)C++代码耗时:0.014

#include<bits/stdc++.h>
using namespace std;int main() {int k=0,n=1e7;clock_t start,end;start=clock();for(int i=0;i<n;i++)k++;end=clock();cout<<(double)(end-start)/CLOCKS_PER_SEC;return 0;
}

(2)Python代码耗时:0.7999107837677002

from time import *
k,n=0,10000000
start=time()
for i in range(n):k+=1
end=time()
print(end-start)

Python 的 for 循环很耗时,比 C++ 的 for 循环慢约 77 倍!

  • 评测用的 OJ 服务器,性能可能比这个好一些,也可能差不多。
  • 对于C++题目,如果题目要求“时间限制: 1s”,那么内部的循环次数 n 应该在 1 亿次以内;
  • 对于同等规模的Python题目,时间限制一般是5 ~ 10s。

二、算法定义

算法(Algorithm) :对特定问题求解步骤的一种描述,是指令的有限序列。有5个特征:

(1) 输入:一个算法有零个或多个输入。

(2) 输出:一个算法有一个或多个输出。

(3) 有穷性:一个算法必须在执行有穷步之后结束,且每一步都在有穷时间内完成。

(4) 确定性:算法中的每一条指令必须有确切的含义,对于相同的输入只能得到相同的输出。

(5) 可行性:算法描述的操作可以通过已经实现的基本操作执行有限次来实现。

1、计算复杂度

  • 把 n 称为问题的数据规模,把程序的复杂度记为 O(n)。
  • 复杂度只是一个估计,不需要精确计算。
  • 例如在一个有 n 个数的无序数列中,查找某个数 a,可能第一个数就是 a,也可能最后一个数才是a。平均查找时间是 n/2 次,但是仍然把查找的时间复杂度记为 O(n)。
  • 在算法分析中,规模 n 前面的系数被认为是不重要的。

2、有哪些复杂度

如下图所示:

三、算法评估 

  • O(1) 计算时间是一个常数,和问题的规模 n 无关。
  • 用公式计算时,一次计算的复杂度就是 O(1),例如hash算法。
  • 在矩阵 A|M|N| 中查找 i 行 j 列的元素,只需要一次访问 A[i][j]。
  • O(logn) 计算时间是对数。
  • 通常是以 2 为底的对数,每一步计算后,问题的规模减小一倍。例如在一个长度为 n 的有序数列中查找某个数,用折半查找的方法,只需要 logn 次就能找到。
  • O(n) 计算时间随规模 n 线性增长。在很多情况下,这是算法能达到的最优复杂度,因为对输入的 n 个数,程序一般需要处理所有的数,即计算 n 次。例如查找一个无序数列中的某个数,可能需要检查所有的数。
  • O(nlogn) 算法可能达到的最优复杂度。
  • 快速排序算法是典型例子。
  • O(n^2) 一个两重循环的算法,复杂度是O(n^2)。
  • 例如冒泡排序,是典型的两重循环。
  • O(n^3)、 O(n^4)等等。
  • O(2n) 一般对应集合问题。
  • 例如一个集合中有 n 个数,要求输出它的所有子集。
  • O(n!) 在集合问题中,如果要求按顺序输出所有的子集,那么复杂度就是 O(n!)

1、分类

  • 把上面的复杂度分成两类:
  • 多项式复杂度,包括 O(1)、 O(n)、O(nlogn)、 O(nk)等,其中k是一个常数;
  • O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3)
  • 指数复杂度,包括O(2n)、O(n!)等。
  • O(2n) < O(n!) < O(n^n)

2、易解问题——难解问题:用多项式时间来区分

  • 一个算法是多项式复杂度:“高效”算法。
  • 指数复杂度:“低效”算法。
  • 多项式复杂度的算法,随着规模 n 的增加,可以通过堆叠硬件来实现,“砸钱”是行得通的;
  • 指数复杂度的算法,增加硬件也无济于事,其增长的速度超出了想象力。

3、多项式函数与指数函数的增长对比

4、问题规模和可用算法(个人认为超级重要)

5、选择解题方法

  • 竞赛所给的题目,一般都会有多种解法,它考核的是在限定时间和空间内解决问题。
  • 如果条件很宽松,那么可以在多种解法中选一个容易编程的简单算法,以节约这一题的编码时间,有利于队员做更多的题。简单算法一般指暴力法,不用复杂算法和复杂数据结构,虽然代码的效率低下,但是思路和编码非常简单。
  • 如果给定的时间和空间条件很苛刻,那么能选用的合适算法和数据结构就不多了。要得到100%的分数,需要用高效复杂的算法。如果不会复杂算法或时间来不及,可以用暴力法获得部分分数。

6、例题举例

求和  2022年第十三届蓝桥杯省赛,lanqiaoOJ 题号 2080

题目如下图:

(1)暴力法(可拿部分的分)

(2)前缀和 (AC)

以上, 算法复杂度分析

祝好!

 


http://www.ppmy.cn/news/9110.html

相关文章

ArrayList iterator源码分析,为什么迭代器删除元素不会报错

写这篇文章的原因要从前不久的一件事说起。 有一天&#xff0c;朋友问我&#xff0c;“ArrayList遍历中删除元素会怎么样”&#xff1f; 我当时脑子里第一想到的就是forEach这种循环方式&#xff0c;没多想就回答他&#xff1a;“当然会报错了。” 朋友再问&#xff1a;“如…

公司业财一体化详解

一、传统财务会计如何手工做账1.没有财务系统&#xff08;软件&#xff09;时公司会计用手工记账&#xff0c;流程包括&#xff1a;建立总账&#xff1b;首先建立账簿&#xff0c;登记会计账簿时&#xff0c;应当将会计凭证日期、编号、业务内容摘要、金额和其他有关资料逐项计…

STM32配置LED模块化

文章目录前言一、LED的模块化二、GPIO初始化详细解析三、LED代码封装总结前言 本篇文章将带大家深入了解GPIO的配置&#xff0c;并带大家实现LED模块化编程。 一、LED的模块化 什么叫模块化编程&#xff1f;我的理解就是每一个模块都分别写成对应的.c和.h文件&#xff0c;有…

【小程序】如何开发属于自己的一款小程序

文章目录小程序简介概念小程序与普通网页开发的区别微信开发者工具小程序代码构成项目结构JSON 配置文件WXML 模板WXSS 样式JS 逻辑交互小程序的宿主环境宿主环境简介通信模型运行机制组件常用的视图容器类组件常用的基础内容组件其它常用组件API协同工作小程序成员管理小程序的…

【计算机模型机设计】8指令多周期(硬布线)MIPS CPU设计报告

2023年第一篇文章来咯~ 8指令多周期&#xff08;硬布线&#xff09;MIPS CPU设计报告一、设计概述&#xff08;基本类似于上一篇&#xff09;1.1设计目的1.2设计任务1.3设计要求1.4技术指标二、总体方案设计2.1主要功能部件2.2数据通路设计三、详细设计与实现3.1主要功能部件的…

【Vim】基本操作及命令集详解

概述 Vim 是从 vi 发展出来的一个文本编辑器。vi 内置在Linux系统中&#xff0c;是vim的简化版编辑器&#xff0c;vim则需要进行安装使用。Vim代码补全、编译及错误跳转等方便编程的功能特别丰富&#xff0c;可以实现高效率移动和高效的输入&#xff0c;在程序员中被广泛使用。…

用python整个活(5) ——还原方阵游戏

目录 &#x1f3c6;一、前言 &#x1f3c6;二、游戏规则 &#x1f3c6;三、numpy模块 &#x1f3c6;四、第一步&#xff1a;大循环and获取规格 &#x1f3c6;五、第二步&#xff1a;初始化棋盘 &#x1f3c6;六、第三步&#xff1a;标注矩阵功能&#xff08;难&#xff09; &am…

关于进程间的通信方式的总结

一、背景 在人类思想史上,马克思第一次对人的本质作出科学界定:人的本质是一切社会关系的总和。时间万物都存在或多或少的关系。那么人除了天生父子这样的家族关系&#xff0c;还有后天 通过 语言 &#xff0c;这样区别于其他动物的方式来进行和其他人的交流产生关系。 在计算…