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

目录

二、计算步骤

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

第二步:快速算总数

第三步:去掉系数得答案

三、常见规则

[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ⁿ)(指数级)

相关推荐
AI小老六2 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术3 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
亦暖筑序4 小时前
Java 8老系统AI Workflow实战:把一次性AI对话升级成可恢复工作流
java·后端
Asize4 小时前
初识DFS 与 BFS:递归、队列与图遍历
算法
敲代码的彭于晏4 小时前
Bean 生命周期完全图解:前端同学也能看懂的 Spring 核心机制
java·前端·后端
plainGeekDev6 小时前
ButterKnife → ViewBinding
android·java·kotlin
罗西的思考17 小时前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
CSharp精选营20 小时前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
美团技术团队21 小时前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
像我这样帅的人丶你还21 小时前
Java 后端详解(四):分页与搜索
java·javascript·后端