如何计算时间复杂度(上)

目录

二、计算步骤

第一步:只看循环,不看内容

第二步:快速算总数

第三步:去掉系数得答案

三、常见规则

[1. 常数规则](#1. 常数规则)

[2. 顺序结构](#2. 顺序结构)

[3. 循环结构](#3. 循环结构)

[(1) 简单循环](#(1) 简单循环)

[(2) 嵌套循环](#(2) 嵌套循环)

[(3) 多层循环](#(3) 多层循环)

[4. 对数循环](#4. 对数循环)

[5. 递归算法](#5. 递归算法)

[(1) 简单递归](#(1) 简单递归)

[(2) 分治递归(二分)](#(2) 分治递归(二分))

[(3) 斐波那契递归](#(3) 斐波那契递归)


一、基本概念

时间复杂度:描述算法执行时间随输入规模增长的变化趋势

二、计算步骤

注意点:计算时间复杂度不能只看代码,要结合里面的思想

例子:

java 复制代码
void practice(int n) {
    int count = 0;
    for (int i = n; i > 0; i /= 2) {        // O(log n)
        for (int j = 0; j < i; j++) {       // O(i)
            count++;
        }
    }
}

第一步:只看循环,不看内容

java 复制代码
for (int i = n; i > 0; i /= 2) {    ← 看这个循环
    for (int j = 0; j < i; j++) {   ← 看这个循环
        // 里面是什么不管!都是O(1)
    }
}

第二步:快速算总数

外循环:i = n, n/2, n/4, ... 1 → 大约 log n

内循环每轮次数:

  • 第1轮:n 次

  • 第2轮:n/2 次

  • 第3轮:n/4 次

  • ...

快速求和 :n + n/2 + n/4 + ... ≈ 2n

第三步:去掉系数得答案

2n → 去掉系数2 → O(n)

三、常见规则

1. 常数规则

int x = 10; // O(1)

int y = x + 5; // O(1)

常数操作的时间复杂度:O(1)

2. 顺序结构

时间复杂度为各段复杂度之和

operation1(); // O(n)

operation2(); // O(log n)

// 总复杂度:O(n) + O(log n) = O(n)

3. 循环结构

(1) 简单循环

java 复制代码
for (int i = 0; i < n; i++) {           // 外循环 n 次
    for (int j = 0; j < n; j++) {       // 内循环 n 次
        // O(1) 操作
    }
}

复杂度:n × O(1) = O(n)

(2) 嵌套循环

java 复制代码
for (int i = 0; i < n; i++) {           // 外循环 n 次
    for (int j = 0; j < n; j++) {       // 内循环 n 次
        // O(1) 操作
    }
}

复杂度:n × n × O(1) = O(n²)

(3) 多层循环

java 复制代码
for (int i = 0; i < n; i++) {           // n 次
    for (int j = 0; j < i; j++) {       // 0, 1, 2, ..., n-1 次
        // O(1) 操作
    }
}

复杂度:0 + 1 + 2 + ... + (n-1) = n(n-1)/2 = O(n²)

4. 对数循环

java 复制代码
int i = 1;
while (i <= n) {
    i = i * 2;      // 每次翻倍
}

复杂度:O(log n)

java 复制代码
int i = n;
while (i > 0) {
    i = i / 2;      // 每次减半
}

复杂度:O(log n)

5. 递归算法

(1) 简单递归

java 复制代码
int factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

递归深度:n ,每层 O(1) ,总复杂度:O(n)

(2) 分治递归(二分)

java 复制代码
int binarySearch(int arr[], int l, int r, int x) {
    if (r >= l) {
        int mid = l + (r - l) / 2;
        if (arr[mid] == x) return mid;
        if (arr[mid] > x) return binarySearch(arr, l, mid - 1, x);
        return binarySearch(arr, mid + 1, r, x);
    }
    return -1;
}

递推式:T(n) = T(n/2) + O(1)

复杂度:O(log n)

(3) 斐波那契递归

java 复制代码
int fib(int n) {
    if (n <= 1) return n;
    return fib(n - 1) + fib(n - 2);
}

递推式:T(n) = T(n-1) + T(n-2) + O(1)

复杂度:O(2ⁿ)(指数级)

相关推荐
超梦dasgg1 天前
Java 生产环境第三方对接安全保障方案
java·开发语言·安全
日月云棠1 天前
9 Double 与 Float —— IEEE 754 浮点数在 Java 中的实现
java·后端
Refrain_zc1 天前
Android 二维码登录轮询机制:从扫码到登录的完整客户端实现
java
z落落1 天前
C#参数区别
java·算法·c#
日月云棠1 天前
5 StringBuffer —— 线程安全的可变字符串
java·后端
happymaker06261 天前
SpringBoot学习日记——DAY06(整合MyBatisPlus的其他功能)
java·spring boot·学习
Refrain_zc1 天前
Android 播放器进度条改造实践:句级音频列表映射秒级时间轴
java
我命由我123451 天前
Bugly - Bugly 基本使用( App 质量追踪平台)
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
c238561 天前
vector(下)
数据结构·算法
z落落1 天前
C# 冒泡排序+选择排序 + Array.Sort 自定义排序
数据结构·算法