数据结构和算法(Golang实现)(10)基础知识-算法复杂度主方法
算法复杂度主方法
有时候,我们要评估一个算法的复杂度,但是算法被分散为几个递归的子问题,这样评估起来很难,有一个数学公式可以很快地评估出来。
一、复杂度主方法
主方法,也可以叫主定理。对于那些用分治法,有递推关系式的算法,可以很快求出其复杂度。
定义如下:
如果对证明感兴趣的可以翻阅书籍:《算法导论》。如果觉得太难思考,可以跳过该节。
由于主定理的公式十分复杂,所以这里有一种比较简化的版本来计算:
二、举例
- 二分搜索,每次问题规模减半,只查一个数,递推过程之外的查找复杂度为
O(1)
,递推运算时间公式为:T(n) = T(n/2) + O(1)
。 - 快速排序,每次随机选一个数字作为划分进行排序,每次问题规模减半,递推过程之外的排序复杂度为
O(n)
,递推运算时间递推公式为:T(n) = 2T(n/2) + O(n)
。
按照简化版的主定理,可以知道:
二分查找:a = 1,b = 2,d = 0
,可以知道a = b^d
,所以二分查找的时间复杂度为:O(logn)
。
快速排序:a = 2,b = 2,d = 1
,可以知道a = b^d
,所以快速排序的时间复杂度为:O(nlogn)
。
强调:并非所有递推关系式都可应用主定理,但是大部分情况下都可以。
因为需要较多的数学知识,所以我们只简单介绍到这里。
延伸-计算理论:P和NP问题
在计算机科学中,有一个专门的分支研究问题的可计算性,叫做计算理论。
我们用计算机算法来解决一个问题,如果一个问题被证明很难计算,或者只能暴力枚举来解决,那么我们就不必花大力气去质疑使用的算法是不是错了,为什么这么慢,计算怎么久都没出结果,到底有没有更好的算法。
计算机科学把一个待解决的问题分类为:P
问题,NP
问题,NPC
问题,NP-hard
问题。
一、P 和 NP 问题
类似于O(1)
,O(logn)
,O(n)
等复杂度,规模n
出现在底数的位置,计算机能在多项式时间解决,我们称为多项式级的复杂。
类似于O(n!)
,O(2^n)
等复杂度,规模n
出现在顶部的位置,计算机能在非多项式时间解决,我们称为非多项式级的复杂度。
如果一个问题,可以用一个算法在多项式时间内解决,它称为P
问题(P
为Polynominal
的缩写,多项式)。
比如求1加到100的总和,它的时间复杂度是O(n)
,是多项式时间。
然而有些问题,只能用枚举的方式求解,时间复杂度是指数级别,非多项式时间,但是只要有一个解,我们能在多项式时间验证这个解是对的,这类问题称为NP
问题。
也就是说,如果我们只能靠猜出问题的一个解,然后可以用多项式时间来验证这个解,这些问题都是NP
问题。
所以,按照定义,所有的P
问题都是NP
问题。
计算理论延伸出了图灵机理论,自动机=算法。
有两种自动机,一种是确定性自动机,机器从一个状态到另外一个状态的变化,只有一个分支可以走,而非确定性自动机,从一个状态到另外一个状态,有多个分支可以走。P
问题都可以用两种机器来解决,当非确定性自动机退化就变成了确定性自动机,而NP
问题只能用非确定性自动机来解决。
自动机对N
和NP
问题的定义:
可以在确定性自动机以多项式时间解决的问题,称为P
问题,可以在多项式时间验证答案的问题称为NP
问题。而NP
问题是可以在非确定型自动机以多项式时间解决的问题(NP
两字为Non-deterministicPolynomial
的缩写,非确定多项式)。
数学,计算机科学,哲学,三个学科其实交融在一起,自动机是一台假想的机器,世界其实也可以认为是一个假想的机器,所以世界可以等于一台自动机吗,大家可以发挥想象力,在以后的日子里慢慢体会,建议购买书籍《计算理论》补习相关知识。
二、NPC 和 NP-hard 问题
存在这样一个NP
问题,所有的NP
问题都可以约化成它。换句话说,只要解决了这个问题,那么所有的NP
问题都解决了。其定义要满足2个条件:
- 它得是一个
NP
问题。 - 所有的
NP
问题都可以约化到它。
这种问题称为NP
完全问题(NPC
)。按照这种定义,NP
问题要比NPC
问题的范围广。
那什么是NP-hard
问题,其定义要满足2个条件:
- 所有的
NP
问题都可以约化到它。 - 它不是一个
NP
问题。
也就是说,NP-hard
问题更难,你只要解决了NP-hard
问题,那么所有的NP
问题都可以解决。但是,这个问题本身不是一个NP
问题,也就是解不能在多项式时间内被验证。
比如你有一个交际网,每个人是一个节点,认识的人之间相连。你要通过一个最快、最省钱、最能提升你个人形象、最没有威胁、最不影响你日常生活的方式认识一个萌妹,你怎么证明你认识这个萌妹是最省钱的呢?-来自知乎回答。
我们一旦发现一个问题是NPC
问题,那么我们很难去准确求出其解,只能暴力枚举,靠猜。
三、总结
各类问题可以用这个图来表示:
"P=NP
" 问题的目标,就是想要知道P
和NP
这两个集合是否相等。为了证明两个集合(A
和B
)相等,一般都要证明两个方向:
A
包含B
。B
包含A
。
我们已经说过NP
包含了P
。因为任何一个非确定性机器,都能被当成一个确定性的机器来用。你只要不使用它的“超能力”,在每个分支点只探索一条路径就行。
所以 "P=NP
" 就在于P
是否也包含了NP
。也就是说,如果只使用确定性计算机,能否在多项式时间之内,解决所有非确定性计算机能在多项式时间内解决的问题。
系列文章入口
我是陈星星,欢迎阅读我亲自写的 数据结构和算法(Golang实现),文章首发于 阅读更友好的GitBook。
- 数据结构和算法(Golang实现)(1)简单入门Golang-前言
- 数据结构和算法(Golang实现)(2)简单入门Golang-包、变量和函数
- 数据结构和算法(Golang实现)(3)简单入门Golang-流程控制语句
- 数据结构和算法(Golang实现)(4)简单入门Golang-结构体和方法
- 数据结构和算法(Golang实现)(5)简单入门Golang-接口
- 数据结构和算法(Golang实现)(6)简单入门Golang-并发、协程和信道
- 数据结构和算法(Golang实现)(7)简单入门Golang-标准库
- 数据结构和算法(Golang实现)(8.1)基础知识-前言
- 数据结构和算法(Golang实现)(8.2)基础知识-分治法和递归
- 数据结构和算法(Golang实现)(9)基础知识-算法复杂度及渐进符号
- 数据结构和算法(Golang实现)(10)基础知识-算法复杂度主方法
- 数据结构和算法(Golang实现)(11)常见数据结构-前言
- 数据结构和算法(Golang实现)(12)常见数据结构-链表
- 数据结构和算法(Golang实现)(13)常见数据结构-可变长数组
- 数据结构和算法(Golang实现)(14)常见数据结构-栈和队列
- 数据结构和算法(Golang实现)(15)常见数据结构-列表
- 数据结构和算法(Golang实现)(16)常见数据结构-字典
- 数据结构和算法(Golang实现)(17)常见数据结构-树
- 数据结构和算法(Golang实现)(18)排序算法-前言
- 数据结构和算法(Golang实现)(19)排序算法-冒泡排序
- 数据结构和算法(Golang实现)(20)排序算法-选择排序
- 数据结构和算法(Golang实现)(21)排序算法-插入排序
- 数据结构和算法(Golang实现)(22)排序算法-希尔排序
- 数据结构和算法(Golang实现)(23)排序算法-归并排序
- 数据结构和算法(Golang实现)(24)排序算法-优先队列及堆排序
- 数据结构和算法(Golang实现)(25)排序算法-快速排序
- 数据结构和算法(Golang实现)(26)查找算法-哈希表
- 数据结构和算法(Golang实现)(27)查找算法-二叉查找树
- 数据结构和算法(Golang实现)(28)查找算法-AVL树
- 数据结构和算法(Golang实现)(29)查找算法-2-3树和左倾红黑树
- 数据结构和算法(Golang实现)(30)查找算法-2-3-4树和普通红黑树
数据结构和算法(Golang实现)(10)基础知识-算法复杂度主方法的更多相关文章
- 数据结构和算法(Golang实现)(9)基础知识-算法复杂度及渐进符号
算法复杂度及渐进符号 一.算法复杂度 首先每个程序运行过程中,都要占用一定的计算机资源,比如内存,磁盘等,这些是空间,计算过程中需要判断,循环执行某些逻辑,周而反复,这些是时间. 那么一个算法有多好, ...
- 数据结构和算法(Golang实现)(4)简单入门Golang-结构体和方法
结构体和方法 一.值,指针和引用 我们现在有一段程序: package main import "fmt" func main() { // a,b 是一个值 a := 5 b : ...
- C#基础知识学习(1)方法的重写和隐藏
做了1年多了C#,发现些项目过程中很多基础东西都不是很清晰,基础不够牢固.现在开始复习基础知识并做重点记录 方法需要被重写的时候,可以在方法前加入virtual使方法变成虚方法. 这样我们可以重新写个 ...
- 算法导论 - 基础知识 - 算法基础(插入排序&归并排序)
在<算法导论>一书中,插入排序作为一个例子是第一个出现在该书中的算法. 插入排序: 对于少量元素的排序,它是一个有效的算法. 插入排序的工作方式像许多人排序一手扑克牌.开始时,我们手中牌为 ...
- 1.10 基础知识——GP3.1 制度化 & GP3.2 收集改进信息
摘要: GP3.1是要求建立组织级的关于该过程的制度.标准.模版等全套体系,要求覆盖该PA所有的SP和GP.GP3.2 体现的是持续改进,每个过程都应该收集相应的改进信息. 正文: GP3.1 Est ...
- Oracle优化器基础知识之访问数据的方法
目录 一.访问数据的方法 1.直接访问数据 2.访问索引 一.访问数据的方法 Oracle访问表中数据的方法有两种,一种是直接表中访问数据,另外一种是先访问索引,如果索引数据不符合目标SQL,就回表, ...
- python基础知识02-序列类型的方法
列表的方法: 增:append() insert() extend()只能添加序列类型. .改li[0]= '123' li.insert(2,'123') 2个参数,位置,值 li.remove(' ...
- scrapy基础知识之 使用FormRequest.from_response()方法模拟用户登录:
通常网站通过 实现对某些表单字段(如数据或是登录界面中的认证令牌等)的预填充 使用Scrapy抓取网页时,如果想要预填充或重写像用户名.用户密码这些表单字段, 可以使用 FormRequest.fro ...
- python基础知识五 各类型数据方法补充,转换,分类,编码+坑中菜
3.9各类型数据方法补充,转换,分类,编码,坑中菜 3.9.1数据类型方法补充 1.str:不可变 补充方法 s1.capitalize():首字母大写 s1 = "alex" s ...
随机推荐
- Core + Vue 后台管理基础框架8——Swagger文档
1.前言 作为前后端分离的项目,或者说但凡涉及到对外服务的后端,一个自描述,跟代码实时同步的文档是极其重要的.说到这儿,想起了几年前在XX速运,每天写完代码,还要给APP团队更新文档的惨痛经历.给人家 ...
- SpringMVC框架——视图解析
SpringMVC视图解析,就是将业务数据绑定给JSP域对象,并在客户端进行显示. 域对象: pageContext.request.session.application 业务数据绑定是有ViewR ...
- Delphi10.3的DBGrid中memo类型显示内容而不是(WIDEMEMO)
1]连接好数据库,并显示: 2]增加所有字段: 3]添加事件: // FDQuery1UserName: TWideMemoField; procedure TForm1.FDQuery1Use ...
- 太赞了!阿里几位工程师重写了 《Java 并发编程》
事情是这样的,前些日子和得知一个读者在准备阿里的面试,我蛮有兴趣的跟他聊了起来,随着话题越来越深入,我发现这位读者有意思,他和几位阿里的工程师之前编写了一本 concurrent.redspider. ...
- 《数据库优化》- MySQL视图
一.什么是视图 视图,是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改,视图基于的表称为基表.视图是存储在数据字典里的一条select语句. 通俗地讲,视图就 ...
- 动态规划-01背包-Tallest Billboard
2020-02-07 17:46:32 问题描述: 问题求解: 解法一:BF 看问题规模看似可以直接暴力解决. 如果直接去解肯定是会超时的,因为每次将原空间划分成A区域,B区域和剩余区域的时间复杂度为 ...
- HDFS数据加密空间--Encryption zone
前言 之前写了许多关于数据迁移的文章,也衍生的介绍了很多HDFS中相关的工具和特性,比如DistCp,ViewFileSystem等等.但是今天本文所要讲的主题转移到了另外一个领域数据安全.数据安全一 ...
- sqoop面试题
1.1 Sqoop 在工作中的定位是会用就行1.1.1 Sqoop导入数据到hdfs中的参数 /opt/module/sqoop/bin/sqoop import \ --connect \ # 特殊 ...
- Python第五章-内置数据结构05-集合
Python内置数据结构 五.集合(set) python 还提供了另外一种数据类型:set. set用于包含一组无序的不重复对象.所以set中的元素有点像dict的key.这是set与 list的最 ...
- 模块 psutil 系统信息获取
psutil模块介绍 psutil是一个开源切跨平台的库,其提供了便利的函数用来获取才做系统的信息,比如CPU,内存,磁盘,网络等.此外,psutil还可以用来进行进程管理,包括判断进程是否存在.获取 ...