时间复杂度分析

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

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

时间复杂度具有最差平均最佳三种情况,分别使用 O , Θ , Ω三种符号表示。
常见种类
根据从小到大排列,常见算法 时间 复杂度主要有:
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==1)
    	return 1;
    else
    	return N*algorithm(N-1);
}

在这里插入图片描述
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;
}

在这里插入图片描述朴素模式匹配算法
串的朴素模式匹配算法,主要思想是对主串(S)的每一个字符作为子串(T)的开头,与要匹配的字符串进行匹配。主串(S)的长度为n,要匹配的子串的长度为m,那么朴素模式匹配算法的最好时间复杂度为Ω(1)(第一次匹配就成功),最坏时间复杂度为O(n-m+1)*m),
在这里插入图片描述
平均情况Θ(n+m)(根据等概率原则,平均是(n+m)/2次查找)。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值