• <数据结构基础学习>(二)简单的时间复杂度分析


    一.简单的复杂度分析

    O(1) O(n) O(logn) O(logn) O(n^2)

    大O描述的是算法的运行事件和输入数据之间的关系

    Eg:

    数组求和

    public static int sum(int[] nums){
            int sum = 0;
            for(int num:nums){
                  sum += num;
             }
             return sum;
    }

    O(n),n为nums中的元素个数。算法和n呈线性关系。

    忽略常数,实际时间T=c1*n+c2。

    T = 2 *n +2  O(n)

    T = 2000*n + 10000 O(n)

    T=1*n*n+0 O(n^2)

    T=2*n*n+300n+10 O(n^2)

    大O为渐进事件复杂度,描述n趋近于无穷的情况

    Eg:

    1.添加操作 

    addLast(e)  O(1)

    addFirst(e)    O(n)

    add(index, e)    分析方法,严格计算需要概率论计算期望  O(n/2) = O(n)

    整体来说,添加操作为O(n)的操作,通常情况下,考虑是最坏的情况 

    2.resize O(n)

    3.删除操作

    removeLast()    O(1)

    removeFirst()    O(n)

    remove(index, e)    O(n/2) = O(n)

    整体来说,删除操作为O(n)的操作

    4.修改操作

    set(index, e)  O(1)    数组优势:支持随机访问

    5.查询操作

    get(index)  O(1)

    contains(e)   O(n)

    find(e)   O(n)

    总体来说

    增:O(n)  

    删:O(n)

    改:已知索引O(1);未知索引O(n)

    查:已知索引O(1);未知索引O(n)

    二.均摊时间复杂度与复杂度的震荡

    1.均摊复杂度

    假设capacity = n,n+1次addLast,触发resize,总共进行2n+1次基本操作

    平均,每次addLast(e)操作,进行2次基本操作

    这样均摊计算,均摊时间复杂度是O(1)的。  与当前size无关

    removeLast(e)同理

    2.复杂度的震荡

    同时看addLast和removeLast操作

    当capacity = n,此时size = n,addLast(e)与removeLast(e)都会触发resize

    addLast  扩容O(n)

    removeLast 缩容 O(n)

    addLast 扩容O(n)

    removeLast 缩容O(n)

    ......

    产生了复杂度的震荡

    出现问题原因:removeLast时resize过于着急(Eager)

    解决方案:Lazy

    remove方法中,当size=capacity/4,才将capacity减半,同时需要保证缩容得到的数组空间data.length/2!=0

            if(size == data.length / 2 && data.length / 2 != 0)
                resize(data.length/2);
  • 相关阅读:
    leetcode — simplify-path
    leetcode — climbing-stairs
    leetcode — sqrtx
    leetcode — text-justification
    leetcode — add-binary
    leetcode — plus-one
    leetcode — valid-number
    leetcode — minimum-path-sum
    leetcode — unique-paths-ii
    四维偏序 CDQ套CDQ
  • 原文地址:https://www.cnblogs.com/HarSong13/p/10659934.html
Copyright © 2020-2023  润新知