c/c++语言开发共享C语言关于时间复杂度详解

目录一、时间复杂度1.什么是时间复杂度?2.如何计算?3.常见的时间复杂度:二、空间复杂度1.什么是空间复杂度?2.如何计算?总结一、时间复杂度1.什么是时间复杂度?空间效率,时间效率(较为关注)时间

目录
  • 一、时间复杂度
    • 1.什么是时间复杂度?
    • 2.如何计算?
    • 3.常见的时间复杂度:
  •  二、空间复杂度
    • 1.什么是空间复杂度?
    • 2.如何计算?
  • 总结

    一、时间复杂度

    1.什么是时间复杂度?

    空间效率,时间效率(较为关注)

    时间复杂度:算法中的操作执行次数,为算法的时间复杂度。(不是具体时间,而是执行次数

    2.如何计算?

    时间复杂度

    (1)是一个估算,看表达式中影响大的那一项,如n*n+2n+10中,n*n对整个式子影响最大,故其时间复杂度为n*n,用大o的渐近表示法o(n*n)。

    (2)去掉时间表达式中的常数项乘积,例如,得到一个准确的时间表达式为2n+10,则估算得到的时间复杂度为o(n)

    (3)对于多个未知数时,例如时间表达式为n+m,假设m,n差不多大,则o(m)或o(n);假设m远大于n,则o(m)。

    (4)用常数1去替代所有确定的常数,如准确的时间表达式为100,o(1).

    (5)未知数和常数,滤去常数。

    (6)另外有些算法分为最好,最坏,平均这三种情况。当算法存在这三种情况时,选最坏的时间复杂度,例如假设字符串长度为n,“sdsfrsgtr…”,遍历字符串,求s的时间复杂度,最好o(1),最坏o(n),平均o(n/2)。

    a.  在冒泡排序中,

         第一趟冒泡:n

         第二趟冒泡:n-1

         第三趟冒泡:n-2

         第n趟冒泡:1

         为等差数列,准确次数为:        n*(n+1)/2

    冒泡排序时间复杂度为o(n*n)

    b.  在二分查找/折半查找中:

    假设二分了x次,有1*2*2….*2=n,2^x=n, x=(log2) n

    算法的复杂度计算中,喜欢省略成logn,因为不好写底数,但是写成lg n,是错的。

    c.  在某些阶乘的运算中求时间复杂度:

    long long factorial(size_t n)  {     return n<2 ? n:factorial(n-1)*n;  }

    如factorial(10),则返回factorial(9)*10,在返回到factorial(9)*8…..以此类推返回到

    factorial(1)*2返回到1.(实际是10!)递归了n次,故时间复杂度为o(n)。(特别注意:结返回结果是n!,但是操作的次数是递归了n次,所以时间复杂度为o(n))

    3.常见的时间复杂度:

    C语言关于时间复杂度详解

     二、空间复杂度

    1.什么是空间复杂度?

    空间复杂度是算法运行过程中临时占用存储空间大小的量度,不在意其具体占了多少比特的大小,而是计算变量的个数。

    2.如何计算?

    对照时间复杂度的计算方法。注意:时间是累积的,空间是不累计的,空间可以销毁。

    例题1:消失的数字

    C语言关于时间复杂度详解

    思路1:排序 0 1 2 3 4 5 6 7 9 一次比较,若下一个数与上一个数只差为1,则掠过,若下一个数比上一个数>1,则找到,但时间复杂度不符合。

    思路2:把0到n加到一起,结果ret1,再把数组中的数加到一起ret2,ret1-ret2就是要找的数。

    思路3:异或:相同为0,相异为1。将数组中的数与0-n数互相异或,最后剩下的那个数字就是缺的那个数。

    int missingnumber(int* nums, int numssize){      int x=0;      //先和数组的数进行异或      for(int i=0;i<numssize;++i)      {          x^=nums[i];      }      //在和0-n的数进行异或      for(int j=0;j<numssize+1;++j)      {          x^=j;      }  return x;  }

    要注意0-n数异或时,注意j<numssize+1,它比原数组中元素个数多1。

     例题2:旋转数组

    C语言关于时间复杂度详解

    思路1:保存最后一个数,将其挪到前面来。k次

    void rotate(int* nums, int numssize, int k){      for(int i=0;i<k;++i)      {      int tmp=nums[numssize -1];      for(int end=numssize -2;end >=0;--end)      {          nums[end+1]=nums[end];      }      nums[0]=tmp;      }  }

    但此时时间复杂度为o(n*k),跑不过~

    思路2:以空间换时间,尝试着多消耗一点空间,一次换成。将后k个保存,移到前面来,直接得到。时间复杂度为o(n),空间复杂度为o(n)

    思路3:后k个逆置,前k个逆置,整体逆置(这个实在是太牛了!!)

     

    C语言关于时间复杂度详解

     c代码为:

    //逆置  void reverse(int *nums ,int left,int right){      while(left<right)      {          int tmp=nums[left];          nums[left]=nums[right];          nums[right]=tmp;          ++left;          --right;      }  }  void rotate(int* nums, int numssize, int k)  {      //控制好下标,后n-k个      reverse(nums,numssize-k,numssize-1);      reverse(nums,0,numssize-k-1);      reverse(nums,0,numssize-1);     }

     注意结果可能出错:

     此时需要注意k是否大于n,当k>n时需要取模:k%=numssize

    添加:if(k>numssize){ k%numssize;}

    //逆置  void reverse(int *nums ,int left,int right){      while(left<right)      {          int tmp=nums[left];          nums[left]=nums[right];          nums[right]=tmp;          ++left;          --right;      }  }  void rotate(int* nums, int numssize, int k)  {      if(k>numssize)      {          k%=numssize;      }      //控制好下标,后n-k个      reverse(nums,numssize-k,numssize-1);      reverse(nums,0,numssize-k-1);      reverse(nums,0,numssize-1);     }

    在力扣上运行得到:

    C语言关于时间复杂度详解

    总结

    到此这篇关于c语言关于时间复杂度详解的文章就介绍到这了,更多相关c语言时间复杂度内容请搜索<计算机技术网(www.ctvol.com)!!>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<计算机技术网(www.ctvol.com)!!>!

    需要了解更多c/c++开发分享C语言关于时间复杂度详解,都可以关注C/C++技术分享栏目—计算机技术网(www.ctvol.com)!

    本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

    ctvol管理联系方式QQ:251552304

    本文章地址:https://www.ctvol.com/c-cdevelopment/1022764.html

    (0)
    上一篇 2022年1月8日
    下一篇 2022年1月8日

    精彩推荐