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

目录

二、计算步骤

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

第二步:快速算总数

第三步:去掉系数得答案

三、常见规则

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

相关推荐
wuweijianlove1 小时前
算法性能的渐近与非渐近行为对比的技术4
算法
一定要AK2 小时前
Spring 入门核心笔记
java·笔记·spring
A__tao2 小时前
Elasticsearch Mapping 一键生成 Java 实体类(支持嵌套 + 自动过滤注释)
java·python·elasticsearch
_dindong2 小时前
cf1091div2 C.Grid Covering(数论)
c++·算法
AI成长日志2 小时前
【Agentic RL】1.1 什么是Agentic RL:从传统RL到智能体学习
人工智能·学习·算法
KevinCyao2 小时前
java视频短信接口怎么调用?SpringBoot集成视频短信及回调处理Demo
java·spring boot·音视频
迷藏4942 小时前
**发散创新:基于Rust实现的开源合规权限管理框架设计与实践**在现代软件架构中,**权限控制(RBAC)** 已成为保障
java·开发语言·python·rust·开源
黎阳之光2 小时前
黎阳之光:视频孪生领跑者,铸就中国数字科技全球竞争力
大数据·人工智能·算法·安全·数字孪生
skywalker_112 小时前
力扣hot100-3(最长连续序列),4(移动零)
数据结构·算法·leetcode
6Hzlia2 小时前
【Hot 100 刷题计划】 LeetCode 17. 电话号码的字母组合 | C++ 回溯算法经典模板
c++·算法·leetcode