什么是时间复杂度

作为一个处在学习之路的渣渣,被一个时间复杂度的题给难倒了,然后我就思考了一下什么是时间复杂度。虽然在学校学习了了算法的课程,但是仔细一想,对于时间复杂度还真是不怎么懂。于是重新学习,记下自己的一些理解。

1.时间复杂度

提到时间复杂度,第一时间想到的是算法,简单说,算法就是你解决问题的方法,而你用这个方法解决这个问题所执行的语句次数,称为语句频度或者时间频度,记为T(n)。

那么问题来了,我们为什么要引入这些个概念呢。因为我们想要的是执行一个算法耗费的时间,这个时间理论上可以得到,但是,要得到这个时间就必须要上机测试,但是有这个必要吗?我们需要知道的是哪一个算法需要的时间多,哪一个算法需要的时间少,这样就可以了。而且,算法的耗时和语句的执行次数是成正比的,即语句执行越多,耗时越多。这也就是我们引入概念的原因。

在上面提到的时间频度T(n)中,n是指算法的规模,n不断的变化,T(n)就会不断的变化,而这些变化的规律是怎样的呢?于是我们引入了时间复杂度的概念。

什么是时间复杂度,算法中某个函数有n次基本操作重复执行,用T(n)表示,现在有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。通俗一点讲,其实所谓的时间复杂度,就是找了一个同样曲线类型的函数f(n)来表示这个算法的在n不断变大时的趋势 。当输入量n逐渐加大时,时间复杂性的极限情形称为算法的“渐近时间复杂性”。

我们用大O表示法表示时间复杂性,它是一个算法的时间复杂性。大O表示只是说有上界但并不是上确界。

“大O记法”:在这种描述中使用的基本参数是 n,即问题实例的规模,把复杂性或运行时间表达为n的函数。这里的“O”表示量级 (order),比如说“二分检索是 O(logn)的”,也就是说它需要“通过logn量级的步骤去检索一个规模为n的数组”记法 O ( f(n) )表示当 n增大时,运行时间至多将以正比于 f(n)的速度增长。

时间复杂度对于算法进行的分析和大致的比较非常有用,但是真正的情况可能会因为一些其他因素造成差异。比如一个低附加代价的O(n2)算法在n较小的情况下可能比一个高附加代价的 O(nlogn)算法运行得更快。但是,n越来越大以后,相比较而言较慢上升函数的算法会运行的更快。

上面我引用了一些专业的定义,可能并不是太好理解,下面会写一些常出现的算法时间复杂度和一些实例来解释一下。

2.简单算法的时间复杂度举例

列举一些简单例子的时间复杂度。

O(1)的算法是一些运算次数为常数的算法。例如:

temp=a;a=b;b=temp;

上面语句共三条操作,单条操作的频度为1,即使他有成千上万条操作,也只是个较大常数,这一类的时间复杂度为O(1)。

O(n)的算法是一些线性算法。例如:

sum=0;

for(i=0;i<n;i++)

sum++;

上面代码中第一行频度1,第二行频度为n,第三行频度为n,所以f(n)=n+n+1=2n+1。所以时间复杂度O(n)。这一类算法中操作次数和n正比线性增长。

O(logn) 一个算法如果能在每个步骤去掉一半数据元素,如二分检索,通常它就取 O(logn)时间。举个栗子:

int i=1;

while (i<=n)

i=i*2;

上面代码设第三行的频度是f(n),   则:2*f(n)<=n;f(n)<=log?n,取最大值f(n)= log?n,所以T(n)=O(log?n ) 。

O(n2)(n的k次方的情况)最常见的就是平时的对数组进行排序的各种简单算法都是O(n2),例如直接插入排序的算法。

而像矩阵相乘算法运算则是O(n3)。

举个简单栗子:

sum=0;

for(i=0;i<n;i++)

for(j=0;j<n;j++)

sum++;

第一行频度1,第二行n,第三行n2,第四行n2,T(n)=2n2+n+1 =O(n2)

O(2的n次方) 比如求具有n个元素集合的所有子集的算法

O(n!) 比如求具有N个元素的全排列的算法

时间复杂度按n越大算法越复杂来排的话:常数阶O(1)、对数阶O(logn)、线性阶O(n)、线性对数阶O(nlogn)、平方阶O(n2)、立方阶O(n3)、……k次方阶O(n的k次方)、指数阶O(2的n次方)。

既然说到了这个复杂排序,就必须再多说几句。我们还需要区分算法最坏情况的行为和期望行为。就比如说快速排序,最坏情况运行时间是 O(n2),但期望时间是O(nlogn)。但是我们只要通过一些手段,可以避免最坏情况发生,所以在实际情况中,精心设计的快速排序都能以期望时间运行。

最后再提一下指数的情况。指数算法一般来说太复杂了,所以实际情况下如果不是迫不得已不要用时间复杂度为指数的算法,除非n特别小。

啰啰嗦嗦写了很多最基础的东西,也是想加深一下印象,如果有错误还请指出。

时间: 2024-10-08 03:59:55

什么是时间复杂度的相关文章

在O(n)时间复杂度内找到出现超过一半的数

#include<iostream> using namespace std; bool solver(const int a[],const int n, int & num) { if(NULL == a || 0>= n) return false; ////注意,是小写~ int count = 0; int com = a[0]; for(int i = 1;i<n;i++) { if(0 == count) { com = a[i]; count++; } el

数据结构——时间复杂度

分析算法的时间复杂度: 算法的时间复杂度就是反应了程序执行时间随着输入规模增长而增长的量级,这个标准可以很好的反映出算法的优劣性质. 算法的频度: 一个算法执行所耗费的时间完全可以以程序执行的次数进行估算,程序执行的次数越多,时间复杂度也就越复杂,也就是说算法花费的时间与算法中语句执行的次数成正比例,因此,一个算法中语句执行的次数可以叫做时间频度.记为T(n). 时间复杂度: 由于n表示规模,当n不断变化的时候,T(n)也会随之不断变化,当我们需要知道他的变化趋势的时候,就要引入时间复杂度.一般

如何计算时间复杂度

本文是转载的,原作者不详. 一.概念 时间复杂度是总运算次数表达式中受n的变化影响最大的那一项(不含系数) 比如:一般总运算次数表达式类似于这样: a*2^n+b*n^3+c*n^2+d*n*lg(n)+e*n+f a ! =0时,时间复杂度就是O(2^n); a=0,b<>0 =>O(n^3); a,b=0,c<>0 =>O(n^2)依此类推 eg: (1) for(i=1;i<=n;i++) //循环了n*n次,当然是O(n^2) for(j=1;j<=

leetcode链表--13、median-of-two-sorted-arrays(两个排序数组的中位数,时间复杂度)

题目描述 There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 题目解析:本题关键之处在于时间复杂度要求为O(log(m+n)),本题如果采用合并并排序两数组的方式,时间复杂度为O((m+n)*log(n+m))但是在牛客网上

时间复杂度

一概念 时间复杂度是总运算次数表达式中受n的变化影响最大的那一项(不含系数) 比如:一般总运算次数表达式类似于这样: a*2^n+b*n^3+c*n^2+d*n*lg(n)+e*n+f a ! =0时,时间复杂度就是O(2^n); a=0,b<>0 =>O(n^3); a,b=0,c<>0 =>O(n^2)依此类推 二.计算方法 1.一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道.但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花

统计数组[1-n]中各个元素出现的次数,时间复杂度O(n),空间复杂度O(1),可改变数组结构

* 统计数组中每个元素出现的次数 * 数组长度为N,每个元素范围为[1,N]. * 统计各个元素出现的次数,要求时间复杂度为O(N),空间复杂度为O(1).可以修改数组中元素的值. * * 思路:遍历到每一个元素,将该(元素值 - 1)作为下标值,将该下标的元素赋值(若为正,赋值-1:若为负值,-1) * 最后,每个下标中存储的元素即为统计次数,而下标+1即为元素值. 代码: public static void main(String[] args) { // TODO Auto-genera

算法 笔记1 时间复杂度计算

评价一个算法的优劣应该从三个方面判断 1.时间复杂度 : 执行算法所耗费的时间,即时间复杂度 2.空间复杂度 : 执行算法所耗费的存储空间,主要是辅助空间 3.可读性和可操作性 : 算法应当易于理解,易于编程,易于调试等 时间复杂度 一般情况下,将算法所要求求解问题的输入量称为问题的规模,并用一个正整数n来表示 T(n)就是该算法的时间耗费,他是该算法所求问题规模n的函数 算法中基本操作重复执行的次数时问题规模n的某个函数f(n) 算法的时间量度记为: T(n) = O(F(n)) 时间复杂度的

异或的应用场景:以O(N)时间复杂度查找文章中出现了奇数次的字符串

有个500g大小的文件,程序的运行内存1g,这个文件里边每行一个单词. 正常情况下,每个单词出现的次数为偶数次: 但是,由于程序出现bug,有一个单词出现了奇数次,怎么找到这个单词? import com.google.common.base.Splitter; import org.apache.commons.lang.RandomStringUtils; import java.util.List; /** * Created by kongzheng on 16/3/31. */ pub

算法的时间复杂度和空间复杂度

<算法的时间复杂度和空间复杂度合称为算法的复杂度> --->算法的时间复杂度 (1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道.但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了.并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多.一个算法中的语句执行次数称为语句频度或时间频度.记为T(n). (2)时间复杂度 在刚才提到的时间频度中,n称为问题的规模

算法时间复杂度和空间复杂度详解

算法的时间复杂度和空间复杂度合称为算法的复杂度. 1.时间复杂度 (1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道.但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了.并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多.一个算法中的语句执行次数称为语句频度或时间频度.记为T(n). (2)时间复杂度 在刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时