时间复杂度

leetcode11 盛最多的水

老子叫甜甜 提交于 2020-02-05 06:01:12
利用 双指针方法 解决本题。。(貌似还可以利用栈来解决,不过思路可能要复杂一些。) 本题抛开具体问题,想到双指针解决是降低时间复杂度的关键一步,本题如果利用暴力法解决,时间复杂度为O(n^2), 但是采用双指针法解决,时间复杂度会降低到O(n)。 时间复杂度为O(n),说明问题必须要在遍历一遍数组就解决。 从图上可直观看出,两线段之间形成的区域总是会受到其中较短那条长度的限制。此外,两线段距离越远,得到的面积就越大。 我们在由线段长度构成的数组中使用两个指针,一个放在开始,一个置于末尾。 此外,我们会使用变量 maxarea来持续存储到目前为止所获得的最大面积。 在每一步中,我们会找出指针所指向的两条线段形成的区域,更新 maxarea,并将指向较短线段的指针向较长线段那端移动一步。 class Solution { public: int maxArea(vector<int>& height) { int L = 0; int R = height.size()-1; int max_Area = 0; while(L!=R){ int temp = min(height[L],height[R])*(R-L); if(temp>max_Area) max_Area = temp; if(height[L]<height[R]){ L++; }else{ R--; } }

素数之埃氏筛法&欧拉筛法

给你一囗甜甜゛ 提交于 2020-02-05 03:32:11
素数的判断   判断数n是否为一个素数,基本方法为从2开始向后枚举,若n不能被2,3,4,…,n-1整除,则n为素数,该判断方法的时间复杂度为 O ( n ) O(n) O ( n ) ;更快的方法为,当枚举至 n \sqrt n n ​ 时即可判断是否为素数,该判断方法的时间复杂度为 O ( n ) O(\sqrt n) O ( n ​ ) 。 代码如下: //写法1,其中sqrt函数位于头文件<math.h>,double sqrt(double a) bool isPrime ( int n ) { if ( n <= 1 ) return false ; //特判 int sqr = ( int ) sqrt ( 1.0 * n ) ; //根号n for ( int i = 2 ; i <= sqr ; i ++ ) { //遍历2~根号n if ( n % i == 0 ) return false ; } return true ; } //写法2,当n不接近int型上界时;或i以被定义为long long类型,不至于溢出 bool isPrime ( int n ) { if ( n <= 1 ) return false ; for ( int i = 2 ; i * i <= n ; i ++ ) { if ( n % i == 0 ) return false

算法入门第一课

孤人 提交于 2020-02-05 02:24:37
算法入门第一课 题目一: 时间复杂度(粗描): 1)常数时间复杂度: 不看系数,只要高阶,不要低阶。 2)评价一个流程的好坏: 先看时间复杂度的指标,然后在分析不同数据样本的实际运行时间,也就是“常数时间项”。 在相同时间复杂度的情况下,大量数据进行比较是十分重要的。 题目二: 选择排序,冒泡排序细节的讲解与复杂度分析 额外空间复杂度(用完可以释放的空间): 时间复杂度O(n^2) 额外空间复杂度O(1),与数据状况无关 选择排序:依次选择最小的和前面交换。 冒泡排序:最大的数向后排。 题目三: 插入排序:0 0有序,0 1有序,0~2有序,…挨着交换 时间复杂度:最坏的时候O(n^2):最好O(n) 额外空间复杂度O(1),与数据状况有关。 题目四: 二分法排序:O(log N) 先是有序的数组。每次砍一半。 1)在一个有序的数组中,找某个数是否存在。 2)在一个有序数组中,找>=某个数最左侧的位置 3)局部最小值问题,定义: 1)[0]<[1] 0是局部小 2) [n-1]<[n-2] n-1是局部小 3) [i-1]<[i]<[i+1] i是局部小 问题五: 异或运算的性质与扩展 二进制操作 1) 异或运算 ,不同为一相同位零。(无进位相加) 同或运算 相同为一不同为零 2) 满足交换律和结合律 (无进位相加) 3)不用额外变量交换两个数(不用申请临时变量) 例题

线性数据结构算法

拟墨画扇 提交于 2020-02-04 14:28:45
数据 结构 是 计算机 存储、组织 数据 的方式。数据结构是指相互之间存在一种或多种特定关系的 数据元素 的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储 效率 。数据结构往往同高效的检索 算法 和 索引 技术有关。 图形结构 树形结构 线性结构 集合结构 1.冒泡排序 在进行冒泡法排序(升序)时,将第一个数与后继的数进行比较,如果顺序则继续第二个数与后继的数进行比较;如果逆序则交换位置,继续和后继的数进行比较,完成第一趟冒泡排序。同理,直到数组有序。 如果经过一趟冒泡排序不发生数据交换说明数组原本有序。 最好时间复杂度:O(n) 平均时间复杂度:O(n^2) 最坏时间复杂度: O(n^2) 空间复杂度: O(1) 代码示例 /** * 冒泡排序 * * @param array * @return 相邻数据对比,交互位置 */ public static int[] bubblingSort(int[] array) { //从后一位开始循环对比,直到循环完。 for (int i = array.length - 1; i > 0; i--) { boolean flag = true; //把最大的筛选到最后 for (int j = 0; j < array.length - 1; j++) { if (array[j] > array[j + 1]) {

35、标准模板类(STL)(一),综述、容器及其操作

风流意气都作罢 提交于 2020-02-04 14:16:01
C++的 STL 是一个功能强大的库,它是建立在模板机制上,能够满足用户对存储管理不同类型数据的通用容器和施加在这些容器上的通用算法的巨大需求,并且具有完全的可移植性。因此在寻求程序的解决方案时,应该首先在 STL 中寻求恰当的容器和算法。 STL 是一个通用性极高的编程工具,这种通用性不仅表现在可以使用通用的容器存储和管理任意类型的数据,更重要的是可以对不同的容器施加统一通用的算法和操作。实现这种通用性的关键思想就是:通过引进一个间接层对象对不同结构的数据容器进行统一的访问操作,从而简化了对容器的操作,使得实现操作的算法和函数通用化。这种思想是 STL 的设计原则之一,也是软件设计中一个重要设计思想。 在 STL 中对容器访问的简化和独立就是通过循环子实现的,循环子可以无须依据某种特定容器的数据结构而完成对容器元素的访问,从而使得数据的存储结构与施加于数据的操作相互独立。标准模板库 STL 是由容器类模板,用于访问这些容器的循环子类模板和可以通过循环子在这些容器上实现的各种算法类模板以及函数类模板组成的。STL 为这种标准算法和函数(包括用户定义的函数)借助循环子在容器上实现的应用建立了统一的规则。 容器:可容纳各种数据类型的数据结构。 迭代器:可依次存取容器中元素的东西,连接容器和算法 算法:用来操作容器中的元素的函数模板。例如,STL用sort(

笔试算法题(40):后缀数组 & 后缀树(Suffix Array & Suffix Tree)

冷暖自知 提交于 2020-02-03 00:14:37
议题: 后缀数组(Suffix Array) 分析: 后缀树和后缀数组都是处理字符串的有效工具,前者较为常见,但后者更容易编程实现,空间耗用更少;后缀数组可用于解决最长公共子串问题,多模式匹配问题,最长回文串问题,全文搜索等问题; 后缀数组的基本元素: 给定一个string,其长度为L,后缀指的是从string的某一个位置i(0<=i<L)开始到串末尾(string[L-1])的一个子串,表示为suffix(i); L个suffix(i)按照字典顺序排列并顺序存储在一个数组SA[L]中,则SA[L]称为后缀数组,其元素值存储的是suffix(i)的起始字符在string中的位置; 每一个suffix[i]对应在SA[k]数组中的一个位置,将这个对应的位置存储为Rank[i],时间复杂度为O(N);对于任意两个 suffix[i]和suffix[j],由于知晓其在Rank[L]中的前后位置,所以在O(1)的时间内就可以得出他们的字典序大小关系; 构建SA[i]数组中相邻元素的最长公共前缀(LCP,Longest Common Prefix),Height[i]表示SA[i]和SA[i-1]的LCP(i, j);H[i]=Height[Rank[i]表示Suffix[i]和字典排序在它前一名的后缀子串的LCP大小; 对于正整数i和j而言,最长公共前缀的定义如下: LCP(i, j)

算法与数据结构一:基本概念

a 夏天 提交于 2020-02-02 10:51:31
程序 = 数据结构 + 算法 一、算法的五个特性 算法(algorithm)是解决特定问题求解步骤的描述,在计算机中表现为有限的操作序列。 输入(Input):算法必须有输入量,用以刻画算法的初始条件(特殊情况也可以没有输入量,这时算法本身定义了初始状态); 输出(Output):算法应有一个或以上输出量,输出量是算法计算的结果。没有输出的算法毫无意义。 明确性(Definiteness):算法的描述必须无歧义,以保证算法的实际执行结果是精确地匹配要求或期望,通常要求实际运行结果是确定的。 有限性(Finiteness):算法必须在有限个步骤内完成任务。 有效性(Effectiveness):算法中描述的操作都是可以通过已经实现的基本运算执行有限次来实现(又称可行性)。 二、数据结构 指相互之间存在一种或多种特定关系的数据元素的集合用计算机存储、组织数据的方式。数据结构分别为逻辑结构、(存储)物理结构和数据的运算三个部分。 2.1 逻辑结构 逻辑结构(logical structure) 是指在数据中数据元素之间的相互关系。数据元素之间存在不同的逻辑关系构成了以下4种结构类型。 (1)集合结构:集合的数据元素没有其他关系,仅仅是因为他们挤在一个被称作“集合”的盒子里。 (2)线性结构:线性的数据元素结构关系是一对一的,并且是一种先后的次序,就像a-b-c-d-e-f-g····

[Java高级](三)时间复杂度计算

懵懂的女人 提交于 2020-02-02 04:21:44
正值疫情,家中闭关,早起看新闻确诊人数已过万,不禁唏嘘,在此真切希望长风破浪会有时,直挂云帆济沧海。感激奋斗在一线的医护人员。 时间复杂度 1、概念 2、各时间复杂度介绍 2.1、O(1) 2.2、O(logn)、O(nlogn)对数阶时间复杂度 2.3、O(m+n)、O(m*n) 2.3.1加法法则 2.3.2 乘法法则 2.3.3 循环不仅与n有关,还与执行循环所满足的判断条件有关。 1、概念 时间复杂度是指 算法执行语句 执行的 次数 。 常见的时间复杂度有以下几种: 描述 时间复杂度 常数阶 O(1) 对数阶 O(logn) 线性阶 O(n) 线性对数阶 O(nlogn) 平方阶 O(n²) 立方阶 O(n³) n次方阶 O(mⁿ) 指数阶 O(2ⁿ) 常数阶 阶乘阶 2、各时间复杂度介绍 2.1、O(1) O(1) 是常量级时间复杂度的一种表示方法,并非只执行一行代码。 代码执行时间不是随着n的增大而增大,这样的代码的时间复杂度都是 O(1) 。 注意:通常只要算法中不存在循环、递归,即使代码有很多行,时间复杂度仍是 O(1) 。 2.2、O(logn)、O(nlogn)对数阶时间复杂度 int i = 1 ; while ( i <= n ) { i = i * 2 ; } 代码line3是执行次数最多的,只要算出第3行执行的次数,它 代表的就是整个代码的时间复杂度

数据结构经典十套卷之六

狂风中的少年 提交于 2020-02-02 03:51:13
一、选择题 (30 分 ) 1 . 设一组权值集合 W={2 , 3 , 4 , 5 , 6} ,则由该权值集合构造的 哈夫曼树中带权路径长度之和 为( )。 (A)20 (B) 30 (C) 40 (D) 45 2 .执行一趟 快速排序 能够得到的序列是( )。 (A)[41 , 12 , 34 , 45 , 27] 55 [72 , 63] (B)[45 , 34 , 12 , 41] 55 [72 , 63 , 27] (C)[63 , 12 , 34 , 45 , 27] 55 [41 , 72] (D)[12 , 27 , 45 , 41] 55 [34 , 63 , 72] 3 .设一条单链表的头指针变量为 head 且该链表没有头结点,则其判空条件是( )。 (A) head==0 (B) head->next==0 (C)head->next==head (D)head!=0 4 .时间复杂度不受数据初始状态影响而恒为 O(nlog2n) 的是( )。 (A) 堆排序 (B) 冒泡排序 (C) 希尔排序 (D) 快速排序 5 . 设二叉树的先序遍历序列和后序遍历序列正好相反,则该二叉树满足的条件是( )。 解: DLR LRD (A) 空或只有一个结点 (B) 高度等于其结点数 (C) 任一结点无左孩子 (D) 任一结点无右孩子 6 .

如何从亿量级中判断一个数是否存在?

我只是一个虾纸丫 提交于 2020-02-02 02:21:42
该问题是这样的: 假如给你20亿个非负数的int型整数,然后再给你一个非负数的int型整数 t ,让你判断t是否存在于这20亿数中,你会怎么做呢? 有人可能会用一个int数组,然后把20亿个数给存进去,然后再循环遍历一下就可以了。 想一下,这样的话,时间复杂度是O(n),所需要的内存空间 4byte * 20亿,一共需要80亿个字节, 大概需要8GB的内存空间,显然有些计算机的内存一次是加载不了这么这么多的数据的。 初步优化 按照上面的做法,时间复杂度是O(n),内存是8GB,实际上我们是可以把时间复杂度降低到O(1)的。 例如我们可以这样来存数据,把一个int非负整数n作为数组下标,如果n存在,则对应的值为1,如果不存在,对应的值为0。例如数组arr[n] = 1,表示n存在,arr[n] = 0表示n不存在。 那么,我们就可以把20亿个数作为下标来存,之后直接判断arr[t]的值,如果arr[t] = 1,则代表存在,如果arr[t] = 0,则代表不存在。这样,我们就可以把时间复杂度降低到O(1)。不过空间复杂度我们并没有降低。还稍微大了点。 由于int非负整数一共有 2^31 个,所以数组的大小需要 2^32 这么大。 这里可能有人说也可以用HashSet来存啊,时间复杂度也是近似O(1)。不过这里需要说明的是,HashSet里面存的必须是对象