美文网首页
算法复杂度O(1),O(N),O(N^2)

算法复杂度O(1),O(N),O(N^2)

作者: 神的漾 | 来源:发表于2020-11-12 20:14 被阅读0次
    算法复杂度

    上图对应的是算法复杂度的图片,X轴对应的是n(问题规模),Y轴对应的是执行的运行时间.

    O(1)

    O(1)就是最低的时空复杂度了,也就是耗时/耗空间与输入数据大小无关,无论输入数据增大多少倍,耗时/耗空间都不变.哈希算法就是典型的O(1)时间复杂度,无论数据规模多大,都可以在一次计算后找到目标(不考虑冲突的话),冲突的话比较麻烦,指向的value会做二次hash到另外一块存储区域.
    例子
    从上面的图片我们可以看到O(1)的复杂度是恒定的,一点波澜都没有,什么是O(1)呢,就比如你是一个酒店的管理员,你负责管理酒店的钥匙,你很聪明,你把酒店的100把钥匙放在了100个格子里面存着,并且把格子从1~100进行了编号,有一天有客人来了,酒店老板说,给我拿10号房间的钥匙给我,你迅速从10号格子里面拿出钥匙给老板,速度非常快,这时候你就是一个电脑了,老板跟你说拿几号房房间的钥匙,你只需要看一眼就能知道钥匙在哪里。
    代码对应

    void main(void)
    {
        int i = 0;
        i = 1;
        i = 3;
    }
    

    上面的i=1,i=3都是O(1)的复杂度.

    O(n)

    时间复杂度为O(n),就代表数据量增大几倍,耗时也增大几倍。
    比如常见的遍历算法。
    要找到一个数组里面最大的一个数,你要把n个变量都扫描一遍,操作次数为n,那么算法复杂度是O(n).
    例子
    突然,有一天,你的老板给你说,你用100个箱子存100把钥匙,太浪费空间了,你能补能把钥匙上编号一下,然后把钥匙要用绳子穿起来,这样我们可以把这个放箱子的地方再装修一个房间出来。你想了一下,是啊,现在房价这么贵,这样能多赚点钱。所以你就不能通过上面的方法来找到钥匙了,老板跟你说,给我拿45号房间的钥匙出来,你就需要从100个钥匙里面挨个找45个房间的钥匙。
    O(n)是随着样本数增加复杂度按指数增加的,如果你的酒店老板把酒店的房间增加到一万个,然后有一天,老外不小心把穿钥匙的绳子弄断了,我了个叉叉叉,这时候老板说,老王快把98号房间的钥匙给我,老王惨爆了~~~我们假设如果老王的老板酒店有两万个房间呢?
    对应代码

    for(int i = 1; i<=100: i++)
    {
        if(i == 45) 
             printf("Find it\n");
    }
    

    O(n^2)

    时间复杂度O(n2),就代表数据量增大n倍时,耗时增大n的平方倍,这是比线性更高的时间复杂度。比如冒泡排序,就是典型的O(n2)的算法,对n个数排序,需要扫描n×n次

    双层循环
    用冒泡排序排一个数组,对于n个变量的数组,需要交换变量位置n2次,那么算法复杂度就是O2.
    例子
    随着经济发展越来越好,你的老板把酒店扩大了,有100层每一层有100个房间,当然,你还是你,你把每一层的钥匙穿在一起,然后一共就有100个用绳子穿起来的钥匙串。然后老板叫你找钥匙的时候,你先要找到楼层的编号,再对应找到房间的编号,所以大概对应的是这样的代码。
    对应代码
    int main ()
    {
        int key;
        int array[100][100];
        
        for(int i=1;i<100;i++)
            for(int j=1;j<100;j++)
                array[i][j] = i*100 +j;
        scanf("%d",&key);
        for(int i=1;i<100;i++)
            for(int j=1;j<100;j++)
                if(array[i][j] == key)
                    printf("FIND KEY\n");
        return 0;
    }
    

    这个可以看是O(N2) +O(N2) = O(2*N2) 把常数去掉变成O(N2)

    O(logn)(底数一般是2)

    再比如O(log n),当数据增大n倍时,耗时增大log n倍(这里的log是以2为底的,比如,当数据增大256倍时,耗时只增大8倍,是比线性还要低的时间复杂度)。二分查找就是O(log n)的算法,每找一次排除一半的可能,256个数据中查找只要找8次就可以找到目标。
    例子
    这个就像是有一百把钥匙,你突然觉得,我从头找是不是太慢了,我从中间找,比如我要找到23号的房间钥匙,我从中间切开,找到50编号的位置,然后23在150里面,我再把从中间切开变成25,然后23在125之间,我再切开变成12.5,然后23在12.5~25之间,依次找下去,直到找到钥匙。这种查找钥匙的方法的复杂度就是O(log^n)
    对应代码

    /**
     *  折半查找函数
     *
     *  @param arr   数组
     *  @param len   数组长度
     *  @param value 查找元素
     *
     *  @return 返回查找元素的位置
     */
    int searchItem(int arr[],int len, int value){
        int low = 0,high = len-1,mid;
        while (low <= high) {
            mid = (low + high)/2;
            if (value > arr[mid]) {
                low = mid+1;
            }else if (value < arr[mid]){
                high = mid - 1;
            }else{
                return mid;
            }
        }
        return -1;
    }
     
    int main(int argc, const char * argv[]) {
        //数组必须是有序数组
       int a[10] = {1,2,31,45,52,62,73,86,90,100};
        //查找86元素
        int l = searchItem(a,10,86);
        printf("loc = %d\n",l);
        return 0;
    }
    

    O(n log n)

    O(n log n)同理,就是n乘以log n,当数据增大256倍时,耗时增大256*8=2048倍。这个复杂度高于线性低于平方。归并排序就是O(n log n)的时间复杂度。

    参考:https://zhuanlan.zhihu.com/p/52402826
    参考:https://blog.csdn.net/lkp1603645756/article/details/85013126

    相关文章

      网友评论

          本文标题:算法复杂度O(1),O(N),O(N^2)

          本文链接:https://www.haomeiwen.com/subject/irrpbktx.html