《数据结构与算法分析》学习笔记一——算法分析

算法

    算法(algorithm)是为求解一个问题需要遵循的、被清楚地指定的简单指令的集合。

 

数学基础

1. 大O表示法:

      如果存在正常数 c 和 n0 使得当 N ≥ n0时,T(N) ≤ cf(N),则记为T(N) = O(f(N))。

    (描述了T(N)的相对增长率小于等于f(N)的相对增长率。)

2. 大Ω表示法:

      如果存在正常数 c 和 n0 使得当 N ≥ n0时,T(N) ≥ cf(N),则记为T(N) = Ω(f(N))。

    (描述了T(N)的相对增长率大于等于f(N)的相对增长率。)

3. 大Θ表示法:

     如果 T(N) = O(f(N)) 且 T(N) = Ω(f(N)),则 T(N) = Θ(f(N))。

   (描述了T(N)的相对增长率等于f(N)的相对增长率。)

4. 小o表示法:

    如果 T(N) = O(f(N)) 且 T(N) ≠ Θ(f(N)),则 T(N) = o (f(N))。

   (描述了T(N)的相对增长率小于f(N)的相对增长率。)

三个结论

1. 如果T1(N) = O(f(N)) 且 T2(N) = O(g(N)),那么

  (a). 加法法则:T1(N) + T2(N) = max(O(f(N)), O(g(N)));【大O的和等于大O的最大值】

  (b). 乘法法则:T1(N) * T2(N) = O(f(N) * g(N)).【大O的积等于积的大O】

2. 如果T(N) 是一个k次多项式,则T(N) =  Θ(Nk).

3. 对任意常数k,log^k(N) = O(N)。它告诉我们对数增长得非常缓慢。

 

时间复杂度

        一个算法在输入规模为N时运行的耗时称为时间复杂度,常用大O表示。一般来说,它描述了最坏情况下的时间复杂度(平均情况下的时间复杂度需要更加复杂的数学分析)。

        为了简化分析,约定:不存在特定的时间单位。因此,常抛弃一些常数系数和低阶项,从而便于计算大O运行时间。

 

计算时间复杂度的一般法则

法则1——for循环

       一次for循环的运行时间至多是该for循环内语句(包括测试)的运行时间乘以迭代的次数。

法则2——嵌套的for循环

       在一组嵌套循环内部的一条语句总的运行时间为该语句的运行时间乘以该组所有for循环的大小的乘积。

法则3——顺序语句

       将各个语句的运行时间求和即可(这意味着,其中的最大值就是所得的运行时间)

法则4——if/else 语句

       一个if/else语句的运行时间从不超过判断再加上分支语句中运行时间长者的总的运行时间。显然在某些情况下这么估计有些过高,但绝不会估计过低。

 

时间复杂度中的对数规律

       某些分治算法将以O(NlogN)运行。除分治算法外,可将对数最常出现的规律概括为以下一般法则:

       如果一个算法用常数时间O(1)将问题的大小削减为其一部分(通常是1/2),那么该算法就是O(logN)的。另一方面,如果使用常数时间只是把问题减少一个常数(如将问题减少1)那么这种算法那就是O(N)的。

参考链接:https://www.cnblogs.com/mingc/p/5877132.html

常见的时间复杂度

         O(1) <  O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(n^k) < O(2^n) < O(n!) < O(n^n)

附关键代码:

最长子序列和问题(O(n)):

    int MaxSubSequenceSum(vector<int> array) {
        int sum = 0, temp = 0;
        for(int i = 0; i < array.size(); i ++)
        {
             temp = max(0, temp) + array[i];
             sum = max(sum, temp);
        }
        return sum;
    }

求两个整数的最大公约数(O(logn))

    int gcd(int a, int b) {
        return (b == 0) ? a : gcd(b, a % b);
    }

2.19:查找出现次数超过一半的元素(O(n)):

int MoreThanHalfNum_Solution(vector<int> numbers) {
        int ele = numbers[0],flag = 1;
        for(int i = 1; i < numbers.size(); i ++)
        {
            if(numbers[i] == ele)
                flag ++;
            else
            {
                if(flag > 0)
                    flag --;
                else
                {
                    ele = numbers[i];
                    flag ++;
                }
            }
        }
        int count = 0;
        for(int i = 0; i < numbers.size(); i ++)
            if(numbers[i] == ele)
                count ++;
        return count > numbers.size() / 2 ? ele : 0;
    }

 

点赞