算法:常见时间复杂度

常见时间复杂度

  • O(1) - 常数时间复杂度
  • O(log n) - 对数时间复杂度
  • O(n) - 线性时间复杂度
  • O(n log n) - 线性对数时间复杂度
  • O(n^2) - 平方时间复杂度
  • O(2^n) - 指数时间复杂度
  • O(n!) - 阶乘时间复杂度

O(1) - 常数时间复杂度

定义:算法的运行时间与输入规模无关,始终是一个常数。

示例:访问数组的某个元素。

int getElement(int arr[], int index) {return arr[index];
}

解释:无论数组有多大,访问数组中的任何一个元素所需的时间都是固定的。这种操作的时间复杂度是 O(1)。

具体分析

  1. 输入规模:数组 arr 和索引 index
  2. 操作数:只需一次查找和返回操作,无论数组长度。
  3. 应用场景:获取数组中的某个元素、执行简单的算术运算(如加法、乘法)、赋值操作。

O(log n) - 对数时间复杂度

定义:算法的运行时间与输入规模的对数成正比,常见于“每次将问题规模减半”的算法。

示例:二分查找。

int binarySearch(int arr[], int size, int target) {int left = 0, right = size - 1;while (left <= right) {int mid = left + (right - left) / 2;if (arr[mid] == target) return mid;else if (arr[mid] < target) left = mid + 1;else right = mid - 1;}return -1;
}

解释:在有序数组中查找一个元素,每次将搜索范围减半,时间复杂度是 O(log n)。

具体分析

  1. 输入规模:数组 arr 的长度 size 和目标值 target
  2. 操作数:每次比较后,将搜索范围缩小一半,直到找到目标或范围为空。
  3. 应用场景:二分查找、平衡二叉搜索树的查找操作。

O(n) - 线性时间复杂度

定义:算法的运行时间与输入规模成正比,通常是简单的遍历操作。

示例:找到数组中的最大值。

int findMax(int arr[], int size) {int max = arr[0];for (int i = 1; i < size; i++) {if (arr[i] > max) {max = arr[i];}}return max;
}

解释:需要遍历整个数组,随着数组长度的增加,运行时间也线性增加,因此时间复杂度是 O(n)。

具体分析

  1. 输入规模:数组 arr 的长度 size
  2. 操作数:遍历数组中的每个元素,共 n 次比较操作。
  3. 应用场景:遍历数组、线性搜索、统计数组中的元素个数。

O(n log n) - 线性对数时间复杂度

定义:算法的运行时间与输入规模的乘积成正比,其中一个因子是对数。

示例:归并排序。

void mergeSort(int arr[], int left, int right) {if (left < right) {int mid = left + (right - left) / 2;mergeSort(arr, left, mid);mergeSort(arr, mid + 1, right);merge(arr, left, mid, right);}
}void merge(int arr[], int left, int mid, int right) {int n1 = mid - left + 1;int n2 = right - mid;int L[n1], R[n2];for (int i = 0; i < n1; i++)L[i] = arr[left + i];for (int j = 0; j < n2; j++)R[j] = arr[mid + 1 + j];int i = 0, j = 0, k = left;while (i < n1 && j < n2) {if (L[i] <= R[j]) {arr[k] = L[i];i++;} else {arr[k] = R[j];j++;}k++;}while (i < n1) {arr[k] = L[i];i++;k++;}while (j < n2) {arr[k] = R[j];j++;k++;}
}

解释:归并排序将数组分成两半分别排序并合并,每个层级的合并操作是 O(n),而分层级数是 O(log n),总时间复杂度是 O(n log n)。

具体分析

  1. 输入规模:数组 arr 的长度 n
  2. 操作数:分治递归,每层级进行 n 次合并操作,共 log n 层级。
  3. 应用场景:高效排序算法,如归并排序、快速排序(平均情况)。

O(n^2) - 平方时间复杂度

定义:算法的运行时间与输入规模的平方成正比,通常是嵌套循环。

示例:冒泡排序。

void bubbleSort(int arr[], int size) {for (int i = 0; i < size - 1; i++) {for (int j = 0; j < size - i - 1; j++) {if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}

解释:每次都需要比较和交换未排序部分的所有元素,内外两个循环都遍历数组,运行时间随着输入规模的平方增长,因此时间复杂度是 O(n^2)。

具体分析

  1. 输入规模:数组 arr 的长度 n
  2. 操作数:内外两个循环,每次进行比较和交换,共 n*(n-1)/2 次操作。
  3. 应用场景:简单排序算法,如冒泡排序、选择排序、插入排序。

O(2^n) - 指数时间复杂度

定义:算法的运行时间与输入规模的指数成正比,通常是递归算法。

示例:斐波那契数列的递归计算。

int fibonacci(int n) {if (n <= 1) return n;return fibonacci(n - 1) + fibonacci(n - 2);
}

解释:每次计算 fibonacci(n) 都需要计算 fibonacci(n-1) 和 fibonacci(n-2),随着 n 的增大,计算次数呈指数增长,因此时间复杂度是 O(2^n)。

具体分析

  1. 输入规模:整数 n
  2. 操作数:每次递归调用都会分裂成两个递归调用,形成一棵二叉树,共 2^n 次调用。
  3. 应用场景:递归算法,如斐波那契数列计算、汉诺塔问题。

O(n!) - 阶乘时间复杂度

定义:算法的运行时间与输入规模的阶乘成正比,通常是排列组合问题。

示例:排列组合生成。

void permute(int arr[], int l, int r) {if (l == r) {// 输出排列} else {for (int i = l; i <= r; i++) {swap(&arr[l], &arr[i]);permute(arr, l + 1, r);swap(&arr[l], &arr[i]); // 回溯}}
}void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}

解释:每次生成一个排列时,都要考虑每个元素的位置,排列组合的数量是 n!,因此时间复杂度是 O(n!)。

具体分析

  1. 输入规模:数组 arr 的长度 n
  2. 操作数:每次递归都需要交换和回溯,共 n! 次操作。
  3. 应用场景:排列组合问题、旅行商问题(暴力求解)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/51234.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JavaScript】详解Day.js:轻量级日期处理库的全面指南

文章目录 一、Day.js简介1. 什么是Day.js&#xff1f;2. 安装Day.js 二、Day.js的基本用法1. 创建日期对象2. 格式化日期3. 解析日期字符串4. 操作日期5. 比较日期 三、Day.js的高级功能1. 插件机制2. 国际化支持 四、实际应用案例1. 事件倒计时2. 日历应用 在JavaScript开发中…

Android SurfaceFlinger——GraphicBuffer的生成(三十二)

通过前面的学习我们知道,在 SurfaceFlinger 中使用的生产者/消费者模型,Surface 做为生产者一方存在如下两个比较重要的函数: dequeueBuffer:获取一个缓冲区(GraphicBuffer),也就是 GraphicBuffer 生成。queueBuffer :把缓冲区(GraphicBuffer)放入缓冲队列中。 …

k3s节点内的服务发现与负载均衡

K3s 是一个轻量级的 Kubernetes 发行版&#xff0c;它简化了 Kubernetes 的安装和管理&#xff0c;同时保持了与 Kubernetes API 的兼容。在 K3s 中&#xff0c;服务发现与负载均衡的机制与标准的 Kubernetes 非常相似。以下是 K3s 中节点内服务发现与负载均衡的主要机制&#…

查看空闲gpu

如果你希望检查 Unix 或 Linux 系统上的 GPU 使用情况&#xff08;特别是查找空闲的 NVIDIA GPU&#xff09;&#xff0c;可以使用 NVIDIA 提供的命令行工具 nvidia-smi。 打开终端并输入以下命令&#xff1a; nvidia-smi 这个命令将输出你的 NVIDIA GPU 的当前状态&#xf…

Python | ValueError: could not convert string to float: ‘example’

Python | ValueError: could not convert string to float: ‘example’ 在Python编程中&#xff0c;类型转换是一个常见的操作。然而&#xff0c;当尝试将一个字符串转换为浮点数时&#xff0c;如果字符串的内容不是有效的浮点数表示&#xff0c;就会遇到“ValueError: could…

labview四字节转浮点数

1.labview四字节转浮点数 2.Labview怎么把串口接收到的数据转换成浮点数&#xff1f; Labview怎么把串口接收到的数据转换成浮点数&#xff1f;

如何跨越 LangChain 应用研发的最后一公里

说 [LangChain] 是现在最流行的 AI 应用开发框架&#xff0c;应该没有人出来反对吧。LangChain 的出现极大地简化了基于大型语言模型&#xff08;LLM&#xff09;的 AI 应用构建难度&#xff0c;如果把 AI 应用比作一个人的话&#xff0c;那么 LLM 相当于这个人的“大脑”&…

c#中Oracle.DataAccess.dll连接数据库的报错处理

通过DataAccess.dll连接Oracle数据库时&#xff0c;报如下错误 The provider is not compatible with the version of Oracle client 最终原因&#xff1a; dll 文件复制不全(4个文件必须) oracle.dataaccess.dll oci.dll oraociei11.dll oraops11w.dll

基于vue-grid-layout插件(vue版本)实现增删改查/拖拽自动排序等功能(已验证、可正常运行)

前端时间有个需求&#xff0c;需要对33&#xff08;不一定&#xff0c;也可能多行&#xff09;的卡片布局&#xff0c;进行拖拽&#xff0c;拖拽过程中自动排序&#xff0c;以下代码是基于vue2&#xff0c;可直接运行&#xff0c;报错可评论滴我 部分代码优化来自于GPT4o和Clau…

78.WEB渗透测试-信息收集-框架组件识别利用(2)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;77.WEB渗透测试-信息收集-框架组件识别利用&#xff08;1&#xff09; shiro&#xff1a;…

Ubuntu18.04 编译报错: Could NOT find JNI

一、问题描述 Ubuntu18.04 编译报错 OpenCV 时&#xff0c;出现以下错误&#xff1a; Could NOT find JNI (missing: JAVA_INCLUDE_PATH JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)二、解决方法 先执行以下指令&#xff0c; export JAVA_HOME/usr/lib/jvm/java-8-openjdk-am…

Postman中的高级技巧:实现请求的依赖注入

Postman中的高级技巧&#xff1a;实现请求的依赖注入 在API测试中&#xff0c;依赖注入是一种常见的技术&#xff0c;它允许测试人员在执行请求之前动态地设置参数。Postman作为一个强大的API开发和测试工具&#xff0c;提供了多种方法来实现请求的依赖注入。本文将详细介绍如…

支持向量机 及其分类案例详解(附Python 代码)

支持向量机分类器预测收入等级 我们将构建一个支持向量机&#xff08;SVM&#xff09;分类器&#xff0c;以预测一个人基于14个属性的收入等级。我们的目标是判断收入是否高于或低于每年$50,000。因此&#xff0c;这是一个二元分类问题。我们将使用在此处可用的人口普查收入数…

JDBC基础

目录 一、JDBC概述 二、JDBC搭建 1.注册JDBC驱动程序 2.建立与数据库连接 3.获得Satement执行sql语句 4.关闭与数据库的链接通道 三、PreparedStatement和Statement 1、代码的可读性和可维护性 2、最重要的一点是极大地提高了安全性 四、结果集处理 一、JDBC概述 JD…

0719_驱动1 arm裸机开发与linux驱动开发区别

一、什么是驱动 1.只要有硬件存在的地方&#xff0c;就会有驱动存在 2.在windows操作系统中&#xff0c;usb驱动&#xff0c;网卡驱动&#xff0c;电源驱动...... 3.在linux操作系统中&#xff0c;电源驱动&#xff0c;网卡驱动&#xff0c;内存驱动&#xff0c;EMMC驱动..... …

c语言指针2

文章目录 一、void * 指针二、const关键字1.const修饰变量2.const修饰指针变量2. 1 const放在*的右边2. 2 const放在*的左边2. 3 总结 三、指针的运算3. 1指针的加减运算3. 2 指针 - 指针3. 3 指针的关系运算 四、野指针4. 1 什么叫野指针&#xff1f;4. 1 野指针的成因4.1.1 指…

Poetry入门教程

以前使用模块管理和虚拟环境为pip和Virtualenv组合&#xff0c;随着Rasa、Dify等开源项目逐步使用Poetry模块管理&#xff0c;也开始尝试使用Poetry。本文简要介绍Poetry入门操作。 1.Poetry安装 可参考Poetry官网[1]推荐的安装方式&#xff1a; 通过Windows的Powershell如下…

C++编程: 使用 Nanomsg 进行 PUB-SUB 模式基准测试

文章目录 0. 引言1. Nanomsg简介1.1 可扩展性协议类型1.2 支持的传输机制1.3 NanoMsg 架构与实现 2. PUB-SUB 模式基准测试 0. 引言 Nanomsg 作为一款高性能的通信库&#xff0c;支持多种消息传递模式&#xff0c;其中包括 PUB-SUB&#xff08;发布-订阅&#xff09;。 本篇文…

yolov8环境安装

一、Miniconda Conda 是一个开源的包管理和环境管理系统&#xff0c;它能运行、安装和更新各种包和依赖&#xff0c;同时还能创建隔离的环境。 1.1 下载安装 Miniconda https://repo.anaconda.com/miniconda/Miniconda3-py39_24.5.0-0-Windows-x86_64.exe1.2 打开 Anaconda …

向量数据库(一)

写在前面 最近在学习一些 AI 相关的开发&#xff0c;了解了一些未接触过的东西&#xff0c;其中有一部分是向量数据库&#xff0c;想开一个专题&#xff0c;对相关的内容做一下整理。 内容 什么是向量数据库 一般在我们的日常开发中&#xff0c;使用的数据库存储主要有两种…