时间复杂度

【算法之常见的时间复杂度】

半世苍凉 提交于 2019-11-28 10:10:48
原文: http://blog.gqylpy.com/gqy/341 补充 空间复杂度:用来评估算法占用内存大小的式子。 什么是算法? 算法(Algorithm):一个计算过程,解决文件的方法 时间复杂度 先总结 时间复杂度是用来评估算法运行时间的一个式子(单位)。 一般来说,时间复杂度高的算法比复杂度低的算法慢。 长安的时间复杂度(按效率排序): O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n2logn) < O(n3) 不常见的时间复杂度: O(n!) O(2n) O(nn) 对应的复杂度 下面这张图和上面这张一样,其复杂度不变。 不管for循环内执行多少代码,有x层for循环,复杂度就是O(nx)。 原文: http://blog.gqylpy.com/gqy/341 来源: https://www.cnblogs.com/mypath1/p/11404313.html

python笔记-算法及数据结构1

好久不见. 提交于 2019-11-28 10:01:30
1 算法是一种独立存在的解决问题的思想和方法 2 算法5大特性 2.1 输入(具有0个或多个) 2.2 输出(具有1个或多个输出) 2.3 有穷性(有限步骤可以处理,每个步骤可以在有限时间内处理) 2.4 确切性(算法中每一步都有确切的含义,没有二义性) 2.5 可行性(算法中每一步都是可行的,都能够执行有限次数完成) 3 大O计法 对于算法的时间性质和空间性质,最重要的是其数量级和趋势,这些事分析算法效率的主要部分,而计量算法基本操作数量的规模函数中的常量因子可以忽略不计。 假设存在函数g,使得算法A处理规模为n的问题示例所用时间为T(n)=O(g(n)),则称O(g(n))为算法A的渐进时间复杂度。 4 时间复杂度的几个概念 最优时间复杂度:算法完成工作最少需要多少基本操作 最坏时间复杂度:算法完成工作最多需要多少基本操作 平均时间复杂度:算法完成工作平均需要多少基本操作 5 时间复杂度的几条基本计算规则 ① 基本操作,即只有常数项,认为其时间复杂度为O(1) ② 顺序结构,时间复杂度按加法进行计算 ③ 循环结构,时间复杂度按乘法进行计算 ④ 分支结构,时间复杂度取最大值 ⑤ 判断一个算法效率时,往往只关注操作数量的最高次项,其它次要项和常数项可以忽略 ⑥ 在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度 6 常见时间复杂度时间排序 O(1)<O(logn)

NOIP2017时间复杂度

隐身守侯 提交于 2019-11-28 08:39:38
时间复杂度 (涉及算法:不清楚,可能是模拟吧) 【问题描述(简要)】 小明写了好多循环并给出了时间复杂度,判断小明给出的时间复杂度是否正确。循环结构如下: F i x y 循环体 E 其中“F i x y”表示 新建变量 i(变量 i 不可与未被销毁的变量重名) 初始化为 x 然后判断 i 和 y 的大小关系,若 i小于等于 y 则进入循环,否则不进入。 每次循环结束后 i都会被修改成i+1。 x 和 y 可以是正整数(x 和 y 的大小关系不定)或变量 n。 n 是一个变量,在时间复杂度计算中需保留该变量而不能将其视为常数,该数远大于 100。 “E”表示循环体结束。循环体结束时,这个循环体新建的变量也被销毁。 【输入格式】 输入文件名为 complexity.in。 输入文件第一行一个正整数 t,表示有 t(t≤10)个程序需要计算时间复杂度。 每个程序我们只需抽取其中“F i x y”和“E”即可计算时间复杂度。注意:循环结构允许嵌套。 每个程序的第一行包含正整数 L 和一个字符串,L代表程序行数,字符串表示这个程序的复杂度: O(1) 表示常数复杂度, O(n^w) 表示复杂度为 n^w,w <= 100 ,保证复杂度只有 O(1)和 O(n^w) 两种类型。 接下来 L 行代表程序中循环结构中的“F i x y”或者“E”。 程序行若以“F”开头,表示进入一个循环

包含min函数的栈(第20题)

断了今生、忘了曾经 提交于 2019-11-28 08:12:39
题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。 ac:100% 思路:在push和pop的时候分别重新计算最小值,存入min中,这个时候min方法时间复杂度就是O(1)了 import java.util.Stack; public class Solution { private Stack<Integer> stack = new Stack<Integer>(); private int min; private int size = 0; public void push(int node) { if(size == 0) { min = node; } else { min = node < min ? node : min; } stack.push(node); size++; } public void pop() { if(!stack.empty()) { if(stack.pop() == min) { min = 999999999; Stack<Integer> stackTemp = new Stack<Integer>(); Integer temp; while((temp = stack.pop()) != null) { min = min < temp ? min : temp;

JavaSE要点

与世无争的帅哥 提交于 2019-11-28 07:17:44
1. 正则表达式 匹配验证: 判断给定的字符串是否符合正则表达式所指定的过滤规则,从而可以判断某个字符串的内容是否符合特定的规则(如email地址、手机号码等);当正则表达式用于匹配验证时,通常需要在正则表达式字符串的首部和尾部加上^和$,以匹配整个待验证的字符串。 查找与替换: 判断给定字符串中是否包含满足正则表达式所指定的匹配规则的子串,如查找一段文本中的所包含的IP地址。另外,还可以对查找到的子串进行内容替换。 字符串分割与子串截取: 基于子串查找功能还可以以符合正则表达式所指定的匹配规则的字符串作为分隔符对给定的字符串进行分割。 读懂正则表达式只需要这个文章: https://www.cnblogs.com/zery/p/3438845.html 2.java中带标签的break和continue break, continue不加标签,只能跳出或者继续当前循环,据个例子给你 Lable1: for(int i = 0; i < 5; i++){ label2: for(int j = 0; j < 33; j++){ if(j == 3){ break;//跳出j循环,继续i循环 break Lable1://调出i循环,所有循环结束 break lable2://跳出j循环,继续i循环 continue;//继续j循环 continue Lable1://跳转到i循环

链表的底层原理和实现

爷,独闯天下 提交于 2019-11-28 07:11:31
一、简介   本文从链表的简介开始,介绍了链表的存储结构,并根据其存储结构分析了其存储结构所带来的优缺点,进一步我们通过代码实现了一个输入我们的单向链表。然后通过对递归过程和内存分配的详细讲解让大家对链表的引用和链表反转有一个深入的了解。单向链表实现了两个版本,分别使用循环和递归实现了两个版本的链表,相信大家仔细阅读本文后会对链表和递归有一个深刻的理解。再也不怕面试官让手写链表或者反转链表了。   后面会持续更新数据结构相关的博文。   数据结构专栏: https://www.cnblogs.com/hello-shf/category/1519192.html   git传送门: https://github.com/hello-shf/data-structure.git 二、链表 2.1、链表简介   链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。   使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。   

程序员,你应该知道的数据结构之跳表

我的未来我决定 提交于 2019-11-28 06:27:58
跳表的原理 跳表也叫跳跃表,是一种动态的数据结构。如果我们需要在有序链表中进行查找某个值,需要遍历整个链表,二分查找对链表不支持,二分查找的底层要求为数组,遍历整个链表的时间复杂度为O(n)。我们可以把链表改造成B树、红黑树、AVL树等数据结构来提升查询效率,但是B树、红黑树、AVL树这些数据结构实现起来非常复杂,里面的细节也比较多。跳表就是为了提升有序链表的查询速度产生的一种动态数据结构,跳表相对B树、红黑树、AVL树这些数据结构实现起来比较简单,但时间复杂度与B树、红黑树、AVL树这些数据结构不相上下,时间复杂度能够达到O(logn)。 如何理解跳表? 要理解跳表,我们先从有序链表开始,对于上图中的有序链表,我们要查找值为 150 的节点,我们需要遍历到链表的最后一个元素才能找到,用大O表示时间复杂度就为O(n)。时间复杂度比较高,有没有优化空间呢?答案是肯定的,我们采取空间换时间的概念,对链表抽取出索引层,比如每两个元素抽取一个元素构成新的有序链表,这样索引层的有序链表相对底层的链表来说长度更短、间距更大,改造之后的链表入下图所示: 我们在新的链表中查询 150 ,先从最上层 Level3 开始查找,遍历 Level3 有序链表,遍历两次就查询到了 150 这个节点。相对于初始链表来说,改造后的链表对查询效率有了不少的提升。 改造后的链表就是跳表

程序员,你应该知道的基础排序算法

喜欢而已 提交于 2019-11-28 06:26:40
冒泡排序(Bubble Sort) 原理 冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作。 图解 图片来源网络,侵权即删 性能 时间复杂度:O(n²) 最好时间复杂度:O(n) 最差时间复杂度:O(n²) 平均时间复杂度:O(n²) 空间复杂度:O(1) 代码 public static void bubbleSort(int[] a, int n) { if (n <= 1) return; for (int i = 0; i < n; ++i) { // 如果没有数据交换,则提前退出,提前退出冒泡循环的标志位 boolean flag = false; for (int j = 0; j < n - i - 1; ++j) { if (a[j] > a[j+1]) { // 交换 int tmp = a[j]; a[j] = a[j+1]; a[j+1] = tmp; flag = true; // 表示有数据交换 } } if (!flag) break; // 没有数据交换,提前退出 } } 插入排序(Insertion Sort) 原理 插入排序就像我们玩棋牌一样,每次摸的牌我们都会插入到合适的位置

数据结构与算法前戏

元气小坏坏 提交于 2019-11-28 06:21:33
排序也称排序算法(Sort Algorithm),排序是将一组数据,依指定的顺序进行排列的过程。 排序的分类: 内部排序:指将需要处理的所有数据都加载到内部存储器中进行排序。 外部排序法:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。 常见的排序算法分类 度量一个程序(算法)执行时间的两种方法 事后统计的方法 这种方法可行, 但是有两个问题:一是要想对设计的算法的运行性能进行评测,需要实际运行该程序;二是所得时间的统计量依赖于计算机的硬件、软件等环境因素, 这种方式,要在同一台计算机的相同状态下运行,才能比较那个算法速度更快。 事前估算的方法 通过分析某个算法的时间复杂度来判断哪个算法更优. 时间频度 一句话,时间频度与语句执行次数成正比。 时间频度:一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。 随着n增大,忽略常数项,忽略低次项,忽略系数 时间复杂度 有一个辅助函数f(n), f(n)是T(n)的同数量级函数,记为T(n)=O(f(n) )。 一般情况下,算法中的基本操作语句的重复执行次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/ f(n) 的极限值为不等于零的常数,则称f(n)是T(n

P3952 时间复杂度

孤人 提交于 2019-11-28 04:08:32
—————————————————————————————————————————————————— noip罕见的纯模拟题,细节还是很多的 虽然没有看题解,但也错了很多地方 1,Yes与YES 2,ERR与Err,这个真的毒瘤,一个全大写一个却不是 3,ERR后向栈中添加元素防止RE 4,最后判断栈空、 ————————————————————————————————————————- #include<bits/stdc++.h> using namespace std; int t,lne,flg[500],num[500]; char ch[100]; stack<int>st,bl; int main() { cin>>t; while(t--) { memset(flg,0,sizeof(flg)); memset(num,0,sizeof(num)); while(!st.empty())st.pop(); while(!bl.empty())bl.pop(); int tag=0,lj=0,tab=0,nowtab=0; cin>>lne>>ch; if(lne%2!=0)lj=1; if(ch[2]-'0'!=1)for(int i=4;i<strlen(ch)-1;i++)tag=tag*10+ch[i]-'0'; while(lne--) { char a,b