当前位置:首页 > 技术 > 正文内容

算法复杂度分析:时间与空间的量化评估

访客 技术 2026年7月1日 1

一、复杂度的核心概念

在算法设计中,效率评估主要分为两个维度:运行速度(时间复杂度)和内存占用(空间复杂度)。前者衡量算法执行所需时间随输入规模增长的趋势,后者则关注算法运行期间临时存储空间的增长规律。两者均采用大O渐进表示法进行抽象表达。

二、时间复杂度的推导方法

实际分析时无需精确计数,只需关注主导项。推导步骤如下:

  1. 忽略常数项(如加法中的固定值)
  2. 保留最高阶项
  3. 若最高阶存在且系数不为1,则去除该系数

示例1:双重循环嵌套

void func(int n, int m) {
    int count = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            ++count;
        }
    }
    for (int k = 0; k < 2 * n; ++k) {
        ++count;
    }
    while (m--) {
        ++count;
    }
}

总操作次数为:n×m + 2n + m。当n和m趋于无穷时,主导项为n×m,因此时间复杂度为O(n×m)。

示例2:独立循环组合

void func2(int a, int b) {
    int sum = 0;
    for (int i = 0; i < a; ++i) ++sum;
    for (int j = 0; j < b; ++j) ++sum;
}

由于两循环独立且变量未知,时间复杂度为O(a + b)。若已知关系可进一步简化。

示例3:常量操作

void func3() {
    int val = 0;
    for (int i = 0; i < 50; ++i) ++val;
}

无论循环多少次,只要次数恒定,时间复杂度均为O(1)。

示例4:线性搜索

const char* find_char(const char* str, char target) {
    while (*str != '\0') {
        if (*str == target) return str;
        ++str;
    }
    return nullptr;
}

最坏情况下需遍历整个字符串,长度为N,故时间复杂度为O(N)。通常以最坏情况为准。

示例5:冒泡排序

void bubble_sort(int* arr, size_t len) {
    for (size_t end = len; end > 0; --end) {
        int flag = 0;
        for (size_t i = 1; i < end; ++i) {
            if (arr[i-1] > arr[i]) {
                swap(&arr[i-1], &arr[i]);
                flag = 1;
            }
        }
        if (!flag) break;
    }
}

外层循环共执行约n/2 × (n+1)次,主导项为n²,因此时间复杂度为O(n²)。

示例6:二分查找

int binary_search(int* arr, size_t len, int key) {
    int left = 0, right = len;
    while (left < right) {
        int mid = left + ((right - left) >> 1);
        if (arr[mid] < key) left = mid + 1;
        else if (arr[mid] > key) right = mid;
        else return mid;
    }
    return -1;
}

每次将搜索范围减半,最多需log₂n次比较,时间复杂度为O(log n)。

示例7:递归阶乘

long long factorial(size_t n) {
    return n <= 1 ? n : factorial(n - 1) * n;
}

递归深度为n,每层调用使用常数空间,整体空间复杂度为O(n),时间复杂度也为O(n)。

三、空间复杂度的判定原则

空间复杂度衡量的是算法运行过程中所使用的额外存储空间的最大值,不包括输入本身。

示例1:原地排序

void sort_inplace(int* data, size_t size) {
    for (size_t i = 1; i < size; ++i) {
        int temp = data[i];
        size_t j = i;
        while (j > 0 && data[j-1] > temp) {
            data[j] = data[j-1];
            --j;
        }
        data[j] = temp;
    }
}

仅使用了几个局部变量,空间复杂度为O(1)。

示例2:动态数组生成斐波那契序列

long long* generate_fib(size_t n) {
    if (n == 0) return nullptr;
    long long* result = (long long*)malloc((n + 1) * sizeof(long long));
    result[0] = 0; result[1] = 1;
    for (int i = 2; i <= n; ++i) {
        result[i] = result[i-1] + result[i-2];
    }
    return result;
}

动态分配了n+1个元素的空间,空间复杂度为O(n)。

示例3:递归实现阶乘

long long fact_recursive(size_t n) {
    return n <= 1 ? n : fact_recursive(n - 1) * n;
}

递归调用栈深度为n,每层占用常数空间,因此空间复杂度为O(n)。

四、典型题目练习

  • 缺失数字 —— 要求在O(1)空间内找出缺失整数
  • 旋转数组 —— 实现原地旋转,考察空间利用能力

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

linux screen 用法详情 (nohup 的替代方案)

一、screen 是什么?能干嘛?screen 是一个终端复用器,可以:在一个 SSH 会话中开多个“虚拟终端”SSH 断线后,程序仍然在后台运行随时重新连接到原来的会话特别适合:nohup 的替代方案跑脚本 / 爬虫 / 训练模型运维、远程开发二、安装 screen# CentOS / Rocky / Almayum install -y screen# Debian / Ubuntuapt i...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。