复杂度

时空复杂度分析

故事扮演 提交于 2020-01-20 02:08:00
1. 如何分析、统计算法的执行效率和资源消耗 前言:数据结构和算法本身解决的是“快”和“省”的问题,所以,执行效率是算法一个非常重要的考量指标。如何衡量编写的算法代码的执行效率,主要内容就是:时间、空间复杂度分析。 复杂度分析是整个算法学习的精髓,只要掌握了它,数据结构和算法的内容基本上就掌握了一半(仅供参考)。 1.1 为什么需要复杂度分析 测试结果非常依赖测试环境 测试结果受数据规模 结论: 我们需要一个不用具体的测试数据来测试,就能粗略地估计算法地执行效率地方法。 1.2 大 O 复杂度表示法 定义: 所有代码的执行时间T(n)与每行代码的执行次数n成正比。 公式: T(n) = O(f(n)) 说明: T(n) 表示代码执行的时间;n 表示数据规模的大小;f(n) 表示每行代码执行的次数总和,因为这是一个公式,所以用 f(n) 来表示。公式中的 O,表示代码的执行时间 T(n) 与 f(n) 表达式成正比。 示例: T(n) = O(2n+2)、 T(n) = O(2n2+2n+3),这就是大 O 时间复杂度表示法(2n2代表2乘以n的平方)。当n很大时,公式中的低阶、常量、系数三部分并不左右增长趋势,所以都可以忽略,我们只需记录一个最大量级即可:T(n) = O(n); T(n) = O(n2)。 名称: 大 O 时间复杂度表示代码执行时间随数据规模增长的变化趋势,也叫

sonarqube官方文档翻译之UserGuide

拥有回忆 提交于 2020-01-20 00:01:45
今天继续学习使用SonarQube分析项目代码,为了便于理解,将官方手册用到的翻译出来。 UserGuide Quality Gate Use the Best Quality Gate Configuration 推荐默认配置,对于每一个版本,我们都会根据SonarQube的能力调整默认质量门(Quality Gate)。SonarQube6.2版本新增了三个度量,可靠比,安全比,可维护性比。极力推荐这些新的度量作为默认质量检查的一部分。 注意质量门的条件,必须使用不同的值。举例说明,对于检查绝对数量值没有意义,如:代码行数大于1000. Quality Gate Status 在Project页面上方会显示质量门现有的状态。 若质量门显示状态为“Fails”,你可以注意到是哪些地方出了问题,也可以为你的其他感兴趣的项目提交新的质量门状态。 Security 质量门可以被任何用户访问。若想要改变质量门配置,必须获得管理员允许。项目管理员可以选择哪个项目和哪个质量门关联。 Define Quality Gate 每个质量门条件是有以下部分组合: 度量(measure) 时间(period):值(对于时间)或漏洞(不同值) 比较操作符 警告值(可选) 错误值(可选) 例如,条件组合可能为: measure:Blocker issue period:Value comparison

「题目讨论」数据结构

↘锁芯ラ 提交于 2020-01-19 23:43:34
目录 基础数据结构 一般数据结构 进阶数据结构 树状数组 线段树 例题 线段树的合并 平衡树 常用平衡树 重量平衡树 例题 这篇博客主要是扒 \(wzh\) 大佬的课件的,对于一些做题的思路有个人的理解。 基础数据结构 一般数据结构 都进 \(\text{OI}\) 很久了,这些基础数据结构都应该知道: 栈:后进先出的存储结构。 队列:先进先出的存储结构。 堆:结构是完全二叉树,用于支持插入、删除和求最值的基本操作。完成各操作主要通过每个点的权值一定为子树的最值这个性质展开。 左偏树(可并堆):结构是二叉树,是可以合并的堆。因为插入和删除可以用合并实现因而基本操作只有合并。对每个节点维护往右走到叶子的步数 \(dis\) 。并保证 \(dis(left(x))\le dis(right(x))+1\) , \(dis(right(x))\le dis(left(x))\) 。用归纳可以得出树高级别为 \(\mathcal O(\log⁡n)\) 。基于该性质可以保证复杂度,便在合并操作中维护该性质即可。 进阶数据结构 树状数组 对一个序列进行信息维护,支持单点修改、区间查询,要求信息具有可合并性。 一般只对有可减性信息作维护(例如和、异或和)而不对没有可减性信息作维护(例如最值),维护没有可减性信息将增加树状数组的复杂度。 以维护区间和为例,树状数组将记数组 \(C_i=Sum(i

关于最短路

寵の児 提交于 2020-01-19 15:23:05
关于最短路,大家应该都知道有Dijkstra,SPFA以及Floyd。 此处先提出一个问题: 给定图G,每条边有边权。 求从一点到另一点的边权和最小的路径。 要求图中不能有负回路(否则为NP问题)。 首先提到的便是Floyd。 如果数据范围足够小,相信大家大部分会选择Floyd(为什么呢,后文解释)。 大家都知道Floyd板子好背,不像其它两种算法一样颇为复杂。 但别看它貌似简单,但其实蕴含着大道理,这也是我去清北学堂的时候听hzc老师讲的。 Floyd的储存方法就是用邻接矩阵储存,比较方便。 它的原理是DP,时间复杂度为O(n 3 ),空间复杂度为O(n 2 )。 所以Floyd是不可以用来做数据范围较大的题的。 令f[i][j][k]为从i到j,中途只经过编号1~k的节点的最短路。 考虑是否经过k:   如果经过,那么f[i][j][k]=f[i][k][k-1]+f[k][j][k-1];   否则,f[i][j][k]=f[i][j][k-1]; 直接这样做的空间复杂度是O(n 3 ),我们可以进一步优化。 首先,f[..][..][k]只从f[..][..][k]转移,可以用滚动数组优化。 进一步地,如果经过k,那么只会从fp..[[k][k-1]转移,而f[k][..][k]和f[..][k][k]必然不会这样转移,故可以直接在原数组上迭代。 代码实现: f[i][j

关于最短路

浪子不回头ぞ 提交于 2020-01-19 15:19:05
关于最短路,大家应该都知道有Dijkstra,SPFA以及Floyd。 此处先提出一个问题: 给定图G,每条边有边权。 求从一点到另一点的边权和最小的路径。 要求图中不能有负回路(否则为NP问题)。 首先提到的便是Floyd。 如果数据范围足够小,相信大家大部分会选择Floyd(为什么呢,后文解释)。 大家都知道Floyd板子好背,不像其它两种算法一样颇为复杂。 但别看它貌似简单,但其实蕴含着大道理,这也是我去清北学堂的时候听hzc老师讲的。 Floyd的储存方法就是用邻接矩阵储存,比较方便。 它的原理是DP,时间复杂度为O(n 3 ),空间复杂度为O(n 2 )。 所以Floyd是不可以用来做数据范围较大的题的。 令f[i][j][k]为从i到j,中途只经过编号1~k的节点的最短路。 考虑是否经过k:   如果经过,那么f[i][j][k]=f[i][k][k-1]+f[k][j][k-1];   否则,f[i][j][k]=f[i][j][k-1]; 直接这样做的空间复杂度是O(n 3 ),我们可以进一步优化。 首先,f[..][..][k]只从f[..][..][k]转移,可以用滚动数组优化。 进一步地,如果经过k,那么只会从fp..[[k][k-1]转移,而f[k][..][k]和f[..][k][k]必然不会这样转移,故可以直接在原数组上迭代。 代码实现: f[i][j

启发式合并

房东的猫 提交于 2020-01-18 16:48:25
某$OI$选手写的,其中一些观点看法让我受益颇深 启发式合并 #先来分类 一般来说,$OI$中的名词大概分成这几大类. 思想 : 模拟,贪心,动态规划,模型转换 策略 : 固定策略,随机化策略,启发式策略 算法 : … 显然在合并时使用启发式策略的算法,被称之为启发式合并. #定义 形如在两个对象合并时,参考两个对象(任何类型)的启发式函数,决定谁并入谁的合并,我们称之为启发式合并. 一般地,对象类型是集合,启发式函数为集合的大小,合并方式为小的集合并入大的集合. #一般模型 - 按秩合并 考虑有$n$个元素,分别属于不同的集合,现在要将某两个集合合并,进行多次操作,考虑到按题意模拟,有很大概率被卡成$O(n^{2})$ 所以我们选择按秩合并,即把小的集合并入大的集合,复杂度可以分开每个元素考虑,一个元素从一个集合进入另一个集合的操作占主要复杂度,一个元素从一个集合进入另一个集合仅当另一个集合大于等于当前集合,则可以发现一个元素并入的集合呈指数增长,则一个元素最多被合并$O(lnn)$次,所以总体而言,复杂度为$O(nln^{2}$)的. 几大经典应用 并查集按秩合并: 加上路径压缩成为并查集的两大优化 优先队列的启发式合并: P3377 【模板】左偏树(可并堆) 从来就不可能码什么可并堆,$O(nln^{2}n)$随便水 平衡树的启发式合并: 各种乱搞 #特殊模型 树上启发式合并

【技术分享】GBDT算法-原理篇

ぃ、小莉子 提交于 2020-01-15 17:28:19
本文原作者:蒋凯,经授权后发布。 原文链接: https://cloud.tencent.com/developer/article/1509000 导语 :工业界机器学习大杀器解读。 GBDT是常用的机器学习算法之一,因其出色的特征自动组合能力和高效的运算大受欢迎。 这里简单介绍一下GBDT算法的原理,后续再写一个实战篇。 1、决策树的分类 决策树分为两大类,分类树和回归树。 分类树用于分类标签值,如晴天/阴天/雾/雨、用户性别、网页是否是垃圾页面; 回归树用于预测实数值,如明天的温度、用户的年龄、网页的相关程度; 两者的区别: 分类树的结果不能进行加减运算,晴天+晴天没有实际意义; 回归树的结果是预测一个数值,可以进行加减运算,例如20岁+3岁=23岁。 GBDT中的决策树是回归树,预测结果是一个数值,在点击率预测方面常用GBDT,例如用户点击某个内容的概率。 2、GBDT概念 GBDT的全称是Gradient Boosting Decision Tree,梯度提升决策树。 要理解GBDT,首先就要理解这个B(Boosting)。 Boosting是一族可将弱学习器提升为强学习器的算法,属于集成学习(ensemble learning)的范畴。Boosting方法基于这样一种思想:对于一个复杂任务来说,将多个专家的判断进行适当的综合所得出的判断

数据结构学习笔记——第一章 基本概念

无人久伴 提交于 2020-01-15 01:59:01
数据结构学习笔记——第一章 基本概念 第一章 基本概念 1.1 什么是数据结构 1.1.1 关于数据组织 1.1.2 关于空间使用 1.1.3 关于算法效率 1.1.4 抽象数据类型 什么是数据结构? 抽象数据类型(Abstract Data Type) 1.2 什么是算法 1.2.1 算法的定义 1.2.2 什么是好的算法 1.2.3 复杂度的渐进表示 1.3 应用实例 第一章 基本概念 1.1 什么是数据结构 1.1.1 关于数据组织 1.1.2 关于空间使用 1.1.3 关于算法效率 1.1.4 抽象数据类型 什么是数据结构? 数据对象 在计算机中的组织方式 逻辑结构 物理存储结构 数据对象必定与一系列加在其上的 操作 相关联 完成这些操作所用的方法就是 算法 抽象数据类型(Abstract Data Type) 数据类型 数据对象集 数据集合相关联的操作集 抽象 :描述数据类型的方法不依赖于具体实现 与存放数据的机器无关 与数据存储的物理结构无关 与实现操作的算法和编程语言均无关 只描述数据对象集和相关操作集“ 是什么 ”,并不涉及“ 如何做到 ”的问题 1.2 什么是算法 1.2.1 算法的定义 算法(Algorithm) 一个有限指令集 接受一些输入(有些情况下不需要输入) 产生输出 一定在有限步骤之后终止 每一条指令必须 有充分明确的目标,不可以有歧义

【可并堆】【数据结构】左偏树简介

感情迁移 提交于 2020-01-14 06:43:03
左偏树 Noip大概率翻皮水了,然后先继续xjb学习吧,顺便文化课也是翻皮水大队的:( 今天介绍一种特殊的数据结构:可并堆中的一种->左偏树(好吧其实是因为这种简单易懂代码复杂度较低). 基本介绍 左偏树,故名思义,它是颗向左倾斜的树,其实,它还是棵二叉树,再者,它还具有堆的性质,but,它不是堆. 那么显然,左偏树看起来就像是优化堆一些难以用较优复杂度实现的操作,其实主要就是一个操作:合并. 我们知道,传统的二叉堆,是需要暴力合并的,复杂度为 \(O(sz1+sz2)\) ,而本文所涉及的左偏树,复杂度为$O(log_{2} sz1sz2) $. 首先介绍一个定义:一个节点到其 子树内最近叶节点 的距离称之为这个节点的高度 Height ,简记为 ht . 接下来给出一些左偏树的性质. 基本性质 性质1 堆的性质:对于任意节点 P , \(val_{P}\) <(或>) \(val_{lson[p]}\) 与 \(val_{rson[p]}\) 性质2 \[ht_{lson[P]} \geq ht_{rson[P]}\] 左偏树顾名思义,向左倾斜的树,就是这个性质在图像可视化后的诠释. 性质3 \[ht_{P}=ht_{lson[P]}+1\] 很好理解,由性质2以及叶节点ht为0可以得出. 性质4 对于一棵 \(n\) 节点的左偏树, \(max\{ht\} \leq log_

Algorithms_算法思想_递归篇

*爱你&永不变心* 提交于 2020-01-12 21:55:33
文章目录 引导案例 递归的定义 什么样的问题可以用递归算法来解决 递归如何实现以及包含的算法思 斐波那契数列代码实现 递归的时间复杂度(`2^n`)和空间复杂度(`2^n`) 引导案例 案例一: 分销系统的返利: 比如B是A的下线,C是B的下线,那么在分钱返利的时候A可以分B,C的钱,这时候我们是不是就要分别找B,C的最后上级。这个问题我们一般怎么来解决呢? C–>B–>A 案例二: .斐波那契数列: 1 1 2 3 5 8 13 21 . . . . . . 有什么特点? 从第三个数开始 就等于前面两个数相加; 数论思想:利用数学公式或者定理或者规律求解问题; 算法思想中最难的点:递归+动态规划 树论中(比如二叉树,红黑树)和递归密不可分,所以递归一定要弄明白了。 递归的定义 递归算法是一种直接或者间接调用自身函数或者方法的算法。 通俗来说,递归算法的实质是把问题分解成规模缩小的同类问题的子问题,然后递归调用方法来表示问题的解。 举个生活中的例子 比如我们在某窗口排队人太多了,我不知道我排在第几个,那么我就问我前面的人排第几个, 因为知道他排第几我就知道我是第几了。但前面的人也不知道自己排第几那怎么办呢?他也可以继续往前面问, 直到问到第一个人,然后从第一个人一直传到我这里 我就很清楚的知道我是第几了 。 以上这个场景就是一个典型的递归