时间复杂度

时间复杂度

大O的渐进表示法

大O符号:适用于描述函数渐进行为的数学符号。

推导大O阶的方法:

  1. 用常数1取代运行时间中的所有加法常数。
  2. 在修改后的运行次数函数中,只保留最高阶。
  3. 如果最高阶存在且不是1,则去除与这个项目相乘的常数(系数)。

得到结果就是大O阶。

常见类型时间复杂度

常数循环时间复杂度

无论代码执行了多少行,只要是没有循环等复杂结构,那这个代码的时间复杂度就都是O(1)。

双重(多重)循环时间复杂度

O(n + m + k······)

嵌套循环时间复杂度

如果把 O(n) 的代码再嵌套循环一遍,它的时间复杂度就是 O(n²) 或O(n*n).

strchar的时间复杂度

const char * strchr ( const char * str, int character);
/*while(*str)
{
    if(*str == character)
        return str;
    else
        ++str;
}*/

在时间复杂度计算中,通常假设数组(整型数组和字符数组)或者是字符串的长度是N,和通常使用大小N来表示某种未知(不定)的大小,例如:

有些算法的时间复杂度存在最好、平均和最坏情况:

最坏情况:任意输入规模的最大运行次数(上界) N

平均情况:任意输入规模的期望运行次数 N/2

最好情况:任意输入规模的最小运行次数(下界) 1
当一个算法随着输入的不同,时间复杂度不同,时间复杂度做悲观预期,看最坏的情况。

冒泡排序时间复杂度

for(i = 0; i < n - 1; i++)
{
    int j;
    for(j = 0; j < n - 1 - i; j++)
    {
        ......
    }
}

冒泡排序的时间复杂度,如果通过冒泡排序来排n个数字的话,就需要n-1趟冒泡,外层for循环的次数已经确定是n-1次,

但是内层for循环的次数是不断变换的,当i=0时,内层for循环第一次循环的次数是n-1次,,当i=1时,内层for循环第二次循环的次数是n-2次,所以,内层for循环的次数是不断在改变的,不能两个for循环次数直接相乘。

当for循环嵌套的时候,如果内外for循环的循环次数都是定值的时候,才可以直接相乘得到执行次数,再通过大O方法推导出时间复杂度。

嵌套循环如果有一层循环的循环次数在不断改变的时候,一般都是外层循环次数是定值,内层循环次数会不断改变,这样的话就不可以直接相乘得到执行次数。

如果通过冒泡排序来排n个数的话,外层for循环需要循环n-1次,内层for循环每次循环n-1-i 次,总的执行次数

T(N)=n-1 + n-2 +n-3 + … 1 ,

一共是n-1项相加, 这n-1项代表的是外层for循环的次数,每一项代表的是每一次外层for循环对应的内层for循环的次数。通由等差数列求和公式可知,

T(N)=((n-1+1)( n-1 ) )/2

最高次数项就是(n^2)/2

最终的时间复杂度就是O(n^2)。

二分法查找时间复杂度

在二分查找中,最好的情况就是查找一次就找到了,执行次数是1,则时间复杂度就是O(1),默认数组的长度为N,遍历的时候,则最坏情况就是执行N次,但二分查找,不是暴力查找,时间复杂度不可能是O(N)

对于二分查找,最坏的情况就是两端中间只有一个数字了,,由于二分查找是对半查找,最坏就剩一个数字,反推则有:1 * 2 * 2…*2=N,,假设乘了x个2,则有

2^x=N,

x=log以2为底的N次方

时间复杂度就是O(log以2为底的N次方)简写O(logN)。

二分查找很牛逼,但需要先排序。

阶乘递归的时间复杂度

关于递归求时间复杂度需要掌握两个结论:

1、如果每次函数调用中总的执行次数和递归参数无关,则递归算法的时间复杂度= 递归的次数 x 每次递归函数中的时间复杂度。

2、如果每次函数调用中总的执行次数和递归参数有关,则递归算法的时间复杂度就等于所有的递归调用中执行次数的累加。

在递归算法中,只考虑能递归的部分,即考虑N>=2的时候,对于N<2的情况,当做递归结束的标志。

斐波那契递归的时间复杂度

计算斐波那契数列的时间复杂度的公式:递归算法的时间复杂度= 递归的次数 *每次递归函数中的时间复杂度.

//计算斐波那契递归Fib的时间复杂度
long long Fib(size_t N)
{
    if(N < 3)
        return 1;
    return Fib(N - 1) + Fib(N - 2);
}

2^ Fib(N)

2^1 Fib(N-1) Fib(N-2)

2^2 Fib(N-2)Fib(N-3) Fib(N-3) Fib(N-4)

​ Fib(2)

2^n-1 Fib(1) Fib(2) 右边一些递归会提前结束

Fib(N) = 20+21+22+…+2(N-1)-X( 缺一些递归调用)

=2^N-1-X

O((2^N-1-X)*1) = O(2^N)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值