0
点赞
收藏
分享

微信扫一扫

时间复杂度分析

瑾谋 2022-04-26 阅读 88

算法复杂度主要从时间、空间两个角度评价:

  • 时间:假设运行时间固定,统计算法运行的「计算操作的数量」,以代表算法运行所需时间;
  • 空间:统计在最差情况下,算法运行所需使用的「最大空间」

常见种类
根据从小到大排列,常见算法 时间 复杂度主要有:
O(1) < O(logN) < O(N) < O(NlogN) < O(N2) < O(2N) < O(N!)
在这里插入图片描述
O(1):
1)运行次数与N大小呈常数关系:

int algorithm(int N) {
    int a = 1;
    int b = 2;
    int x = a * b + N;
    return 1;
}

2)以下代码,无论 a 取多大,都与输入数据大小 N 无关:

int algorithm(int N) {
    int count = 0;
    int a = 10000;
    for (int i = 0; i < a; i++) {
        count++;
    }
    return count;
}

O(N):

1)阶乘(N !=1×2×3×…×N):

int algorithm(int N){
    if(N==2)
    	return 3;
    else
    	return algorithm(N-1)*4;
}

2)对于以下代码,虽然是两层循环,但第二层与 N大小无关,因此整体仍与 N呈线性关系:

int algorithm(int N) {
    int count = 0;
    int a = 10000;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < a; j++) {
            count++;
        }
    }
    return count;
}

O(N2):

1)两层循环相互独立,都与 N 呈线性关系:

int algorithm(int N) {
    int count = 0;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            count++;
        }
    }
    return count;
}

2)冒泡排序(冒泡排序的总体时间复杂度为 O(N2))
算法思路:

  1. 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
  3. 针对所有的元素重复以上的步骤,除了最后一个;

代码实现:

int[] bubbleSort(int[] nums) {
    int N = nums.length;
    for (int i = 0; i < N - 1; i++) {
        for (int j = 0; j < N - 1 - i; j++) {
            if (nums[j] > nums[j + 1]) {
            //交换数据
                int tmp = nums[j];
                nums[j] = nums[j + 1];
                nums[j + 1] = tmp;
            }
        }
    }
    return nums;
}

O(2N):
算法中,指数阶常出现于递归,代码如下:

int algorithm(int N) {
    if (N <= 0) 
        return 1;
    int count_1 = algorithm(N - 1);
    int count_2 = algorithm(N - 1);
    return count_1 + count_2;
}

O(N!) :
阶乘阶对应数学上常见的 “全排列” 。即给定 N 个互不重复的元素,求其所有可能的排列方案,则方案数量为:N (N - 1) × (N - 2) × … × 2 × 1 =N !
阶乘常使用递归实现,算法原理:第一层分裂出 N个,第二层分裂出 N - 1个,…… ,直至到第 N 层时终止并回溯。

int algorithm(int N) {
    if (N <= 0) return 1;    
        int count = 0;    
    for (int i = 0; i < N; i++) {        
        count += algorithm(N - 1);    
    }    
    return count;
}

O(logN) :
对数阶与指数阶相反,指数阶为 “每轮分裂出两倍的情况” ,而对数阶是 “每轮排除一半的情况” 。对数阶常出现于「二分法」、「分治」等算法中,体现着 “一分为二” 或 “一分为多” 的算法思想。

设循环次数为 m ,则输入数据大小 N 与 2 m呈线性关系,两边同时取 log2对数,则得到循环次数 m与 log2N呈线性关系,即时间复杂度为 O(logN)。

int algorithm(int N) {
    int count = 0;
    float i = N;
    while (i > 1) {
        i = i / 2;
        count++;
    }
    return count;
}

在这里插入图片描述

举报

相关推荐

0 条评论