时间复杂度与空间复杂度

时间复杂度与空间复杂度

一个程序的优劣主要从时间空间两个维度去考量

一、时间复杂度
时间复杂度是根据算法写成的程序在执行的过程中耗费时间的长度,时间复杂度过高的低效算法可能这辈子都等不到运行结果
比较常见的时间复杂度量级有 O(1),O(n),O(n²),O(logN),O(nlogN),O(2^n)

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

int i = 5:
++i;

2.O(n)
只有一个循环,函数中的语句会执行n次,所以时间复杂度是O(n)

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

3.O(n²)
嵌套了两层循环,函数中的语句会执行n*n次,所以时间复杂度是O(n²)

for(int i = 0,i<n;++i){
     for(int j = 0;j<n;++j){
            j = i;
     }
}

这里要注意嵌套的关系,如果程序如下所示的话,并非嵌套结构的话。第一个for循环时间复杂度是O(n),第二个for循环时间复杂度也是O(n),它们两者是相加的关系所以时间复杂度并不是O(n²)而是O(n)

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

同理嵌套k层循环的时候时间复杂度就是O(n^k)

4.O(logN)

for(int i = 1;i<n:i *= 2){
      j = i;
}

在for循环里每次执行完j=i的语句操作,i都会*2,当执行x次以后i>=n了就会退出循环,所以x = log2^n;所以这个循环的时间复杂度是O(logN),在二分查找中时间复杂度就是O(logN)

5.O(nlogN)
同上,执行n次时间复杂度为logN的程序,他的时间复杂度就是nlogN

for(int m = 0;m<n;++m){
    for(int i = 1;i<n:i *= 2){
         j = i;
    }
}

6.O(2^n)
在使用递归求斐波那契数列问题的时候代码如下:

int fibonacci(int i) {
       if(i <= 0) return 0;
       if(i == 1) return 1;
       return fibonacci(i-1) + fibonacci(i-2);
}

递归算法的时间复杂度 = 递归的次数 * 每次递归的时间复杂度
由于计算fibonacci(5)的时候要计算fibonacci(4),fibonacci(3),计算fibonacci(4)fibonacci(3)的时候又要计算fibonacci(3),fibonacci(2),fibonacci(2),fibonacci(1),递归的次数 = 1+2+4+…所以改递归算法的时间复杂度是O(2^n)

二、空间复杂度
空间复杂度是根据算法写成的程序在执行时占用存储单元的长度,空间复杂度过高的算法可能导致使用的内存超限,造成程序的非正常中断
常见的空间复杂度量级有O(1),O(n),O(logN)

1.O(1)
如果算法在执行的过程中所开辟的空间并不会随着n的变化而变化,那么算法的空间复杂度就是O(1)

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

2.O(n)
在函数执行过程中vector数组大小随着i的增加成线性增长,所以空间复杂度是O(n)

vector<int> res;
for (int i = 0; i < n; i++) {
    res.push_back(i);
}

当使用递归算法的时候,递归算法的空间复杂度 = 每次递归的空间复杂度 * 递归深度(递归调用次数)
递归每次所需的空间都要调用栈,递归深度 = 栈的长度

int fibonacci(int i) {
       if(i <= 0) return 0;
       if(i == 1) return 1;
       return fibonacci(i-1) + fibonacci(i-2);
}

在斐波那契数列中,该算法的每次递归的空间复杂度是常数,递归次数是n,所以该算法的空间复杂度是O(n)

3.O(logN)
在使用递归法二分查找的过程中,每次递归的空间复杂度是常数,递归的次数是logN,所以该算法的 空间复杂度是O(logN)

 int BinarySearchRecursive(int *array, int low, int high, int target)  {  
    if ( low > high )  
        return -1;  
    int mid = ( low + high )/2;  
    if (array[mid] == target )  
        return mid;  
    else if ( array[mid] < target )  
        return BinarySearchRecursive(array, mid+1, high, target);  
    else  
        return BinarySearchRecursive(array, low, mid-1, target);  
}  

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值