时间复杂度

代码题(56)— 最长重复子串、无重复字符的最长子串

醉酒当歌 提交于 2019-11-29 15:14:38
1、最长的重复子串   寻找一个字符串中最长的重复子串    最大后缀方法思路: 1. 用字符串指针数组保存用户输入的字符串的 所有后缀字符串 ; 2. 将后缀字符串集合进行 排序 ; 3. 比较相邻字符串的公共子串长度 ,找到长度最大值,保存相应字符串即为所求   空间复杂度:求长度为n的字符串的后缀,需要O(n)的空间复杂度   时间复杂度:产生后缀数组-时间复杂度O(N)、对后缀数组排序是O(N*NlogN),第一个N表示字符串的比较,后面NlogN使用快排排序。依次检测相邻两个后缀的公共长度-时间复杂度O(N*N)、取出最大公共长度的前缀-时间复杂度O(N)。直接用sort排序,时间复杂度是nlog(n)。 总的时间复杂度是O(N*NlogN) #include<iostream> #include<algorithm> #include<stdio.h> #include <vector> #include<string> #include<sstream> #include<map> #include<set> #include <functional> // std::greater using namespace std; int getCommon(string s1, string s2) { int i = 0; for (; i < s1.size()&&

LeetCode题解001:两数之和

这一生的挚爱 提交于 2019-11-29 12:36:47
两数之和 题目 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素 示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] Java: 方法一:暴力法 暴力法很简单,就是用两遍循环的方式遍历nums class Solution { public int[] twoSum(int[] nums, int target) { for (int i = 0; i < nums.length; i++) { for (int j = i + 1; j < nums.length; j++) { if (nums[j] == target - nums[i]) { return new int[] { i, j }; } } } throw new IllegalArgumentException("No two sum solution"); } } 复杂度分析: 时间复杂度:O(n^2) 对于每个元素,我们试图通过遍历数组的其余部分来寻找它所对应的目标元素,这将耗费 O(n) 的时间。因此时间复杂度为 O(n^2)

第四个知识点 P类复杂问题

女生的网名这么多〃 提交于 2019-11-29 12:26:49
第四个知识点 P类复杂问题 原文地址: http://bristolcrypto.blogspot.com/2014/10/52-things-number-4-complexity-class-p.html 这个是密码学52件事第四篇,和理论密码学的第一篇。在这篇中我被要求定义P类复杂问题。我对计算理论科学知道的非常少当我开始我的PhD,而且我确信很多人和我一样。因此这篇文章从最简单的开始,如果你已经会了你可以跳过前面的部分。首先我会描述复杂性的定义和为什么他很重要,然后我们定义图灵机,最后是P类复杂问题,通过一个例子做总结。 这篇文章主要的内容就是重写 Introduction to the Theory of Computation by Michael Sipser [1],我觉得他对我真的很重要。 Section 1: Complexity and Big O Notation 为了设计高效的程序,我们想知道计算机执行给定任务有多难。问题在于,计算机的处理能力因硬件而异(例如,参考上周的52件事)。所以我们想要一个不依赖与执行任务的机器的具体细节的任务难度的度量。其中一种方法就是限定一个特定型号的计算机执行操作所需要的操作数。这就是所谓的(时间)复杂性理论。 不过操作的数量取决于任务的输入,甚至输入长度相同操作数都不相同。举个栗子

红黑树

一个人想着一个人 提交于 2019-11-29 12:20:54
自平衡二叉查找树 它是为了解决二叉查找树的查找时间复杂度最差是O(n)的问题而发明的数据结构算法。 BST的查找运行时间和BST的高度有关。一个树的高度指的是从树的根开始所能到达的最长的路径长度。 因为二叉搜索树的结构可能是一个链表,在这种情况下,在 BST 中查找节点与在数组(Array)中查找就基本类似了。 如这个例子: 有6个节点,它的时间复杂度是O(n)。假如要查找节点200,那么节点会比较5此,相当于遍历所有节点了。 这太浪费时间了,因此降低树的高度,就可以减少时间复杂度。 我们知道二叉搜索树的搜索节点的最小时间复杂度是 O(log­ 2 n)。 因此找到一个高度和节点数量的最佳比例。让它的时间复杂度维持在 O(log­ 2 n)。 期望是: 如果树中节点的数量为 n,则一棵满足O(log 2 n) 渐进运行时间的 BST 树的高度应接近于比 log 2 n 小的最大整数。 但实际问题是: 如何保证 BST 的拓扑结构始终保持树高度与节点数量的最佳比例? 因为 BST 的拓扑结构与节点的插入顺序息息相关,一种方式是通过数据的乱序来保证。所以必须在插入节点前就得到数据。 但是如果无法掌控数据的来源,怎么做?一种方案是新的节点插入不会打乱BST树的平衡。这种始终维持树的平衡状态的数据结构称为:自平衡二叉查找树。self-balancing binary search tree

第一周任务总结(快速幂)

☆樱花仙子☆ 提交于 2019-11-29 12:16:17
** 快速幂算法总结 快速幂算法的概念 快速幂就是做到让程序快速求幂,减少时间复杂度,使程序更快运行 快速幂的时间复杂度 若题目为求a^n的值,那此时程序的时间复杂度为O(n),但如果使用快速幂,便可以将时间复杂度减少到O(log(n)) 快速幂算法的代码 int qpow ( int a , int b ) //首先输入两个值,表示所要运算的a^b { int ans = 1 ; //对结果赋初值,防止之后程序运行时出错 while ( b ) //当b!=0时运行程序 { if ( b & 1 ) //判断此时是否需要相乘 ans = ans * a ; b >>= 1 ; //让b右移一位 a = a * a ; //不断更新a的次方数 //每运行一次,a的次方数加 1 } return ans ; //得到结果 } 首先输入两个值a,b(a^b),并对ans赋初值为1 开始运算,在b!=0的时候,进入循环 判断b的二进制数的末尾为0或是1,若为0则不相乘,为1则进行相乘 b的值不断更新,每次右移一位(除以2) a的值不断更新,每更新一次次方数加一次 当b=0时,说明对b的分解完成,退出循环 好像有点难以理解 ,再来 举个栗子 例如求2的90次方 如果不用快速幂的话,程序需要运行90次,但快速幂只需要四次 首先输入a(2),b(90),开始运算,此时b(90)!=0,进入循环

关于leetcode刷题详细介绍

我们两清 提交于 2019-11-29 11:15:09
  虽然刷题一直饱受诟病,不过不可否认刷题确实能锻炼我们的编程能力,相信每个认真刷题的人都会有体会。现在提供在线编程评测的平台有很多,比较有名的有 hihocoder,LintCode,以及这里我们关注的 LeetCode。 LeetCode收录了许多互联网公司的算法题目,被称为刷题神器,我虽然早有耳闻,不过却一直没有上面玩过。   据了解,LeetCode 是一个非常棒的 OJ(Online Judge)平台,收集了许多公司的面试题目。相对其他 OJ 平台而言,有着下面的几个优点: 题目全部来自业内大公司的真实面试 不用处理输入输出,精力全放在解决具体问题上 题目有丰富的讨论,可以参考别人的思路 精确了解自己代码在所有提交代码中运行效率的排名 支持多种主流语言:C/C++,Python, Java 可以在线进行测试,方便调试 笔者刷leetcode的主要目的 1、熟悉各互联网公司的算法题目,为找工作做准备。 2、复习以前学过的编程语言,LeetCode支持几乎所有主流编程语言,大家可以用不同语言来做题。 3、熟悉常见的算法和数据结构,LeetCode提供了交流平台,一些大神会将自己的解法贴出来共享,有些巧妙的解法实在令人叫绝。 4、学习别人的编程思维,加快编程的速度,避免常见的BUG。   另外LeetCode的题型都非常简单明了,并不需要的复杂的理解

浅谈缓存与Mysql的区别

試著忘記壹切 提交于 2019-11-29 11:05:00
缓存是互联网公司最常用的组件之一,面试中绝大多数的公司也都会问关于缓存的问题。缓存的作用想必不用说,大家随口就能说出来,存储过热数据,防止数据库访问量多大,加快数据访问速度。甚至有的业务可以拿缓存当数据库用,虽然很不建议这么用,但是既然能这么用,必然有这么用的好处。 缓存和关系型数据库之间的区别其实蛮大的,笔者认为有以下几点吧。 首先,在存储数据的数据结构上就有很大的差别,传统的关系型数据库,就是table、columns,存储数据的颜值比较高(比较符合我们观察数据的习惯),存储方式和格式也多种多样。缓存就不一样了,它是key/value结构的数据,虽然redis中可以支持多种数据格式,但是都是建立在key的基础上,所以从存储数据的多样性方面,关系型数据库暂时还是不可被缓存替代的。 其次,在查询速度方面,肯定是缓存高了,虽然数据库可以建立索引,以Mysql-InnoDB为例,大家都知道他的索引格式是B+Tree,时间复杂度是 O(log(n)) ,而缓存就很明显了,时间复杂度是O(1)。 那么问题来了,为什么k/v这种数据结构的时间复杂度低,Mysql去选择B+Tree这种格式的数据去存储索引呢。 这也和第一点,数据存储有关。原因有两个,次要原因是这种数据结构比较符合磁盘查找数据的动作(与盘片旋转和磁臂移动还有树的高度有关),而把key存在内存里就可以解决这个问题

高效算法之时间复杂度介绍

喜你入骨 提交于 2019-11-29 10:35:13
  上一篇博客已经给大家介绍了一些算法题,明天刚好是中秋了,这里祝大家中秋快乐。刚好赶上数学建模了,今天就先介绍与衡量算法水平的重要指标时间复杂度吧。在时间充裕情况下会更新5+2。之后还会介绍空间复杂度以及python内置函数的时间复杂度。 1.简介 先看一下什么是时间复杂度:   衡量代码的好坏,包括两个非常重要的指标:    运行时间 和 占用空间 。   代码的绝对执行时间是无法估计的,但可以预估代码的基本执行次数。 2.程序中最常见的四种执行方式有 (1) T(n) = kn ,执行次数是线性的。   可以理解为有一个任务,完成全部要达到n,每k个时间完成任务的1/n,则完成全部任务所需要的时间为kn个时间。 (2) T(n) = klog(a)(N) ,执行次数是对数的。   可以理解为有一个任务,完成全部要达到n,每k个时间完成任务的1/a,然后下一个时间完成剩下任务的1/a,依次循环,则完成全部任务所需要的时间为kloa(a)N个时间。 (3) T(n) = k ,执行次数是常量的。   可以理解为有一个任务,完成全部要达到n,则k个时间完成任务的n,也就是需要k个时间完成所有任务,这个是可以得到代码的绝对执行时间的,则完成全部任务所需要的时间为k个时间。 (4) T(n) = 0.5n^2 + 0.5n ,执行次数是一个多项式。   可以理解为有一个任务