C语言三分钟精通时间复杂度与空间复杂度

目录
  • 一、时间复杂度
    • 1)O(n)的含义
    • 2)复杂表达式的简化
    • 3)O(n)不一定优于O(n^2)
    • ​4)递归的时间复杂度
  • 二、空间复杂度
    • 1)O(1)空间复杂度​
    • 2)​​​​​​​O(n)空间复杂度​
    • 3)​​​​​​​O(mn)空间 复杂度​
    • 4)递归算法空间算法复杂度分析​

一、时间复杂度

1)O(n)的含义

  • 程序消耗的时间用算法的操作单元数来表示
  • 假设数据的规模为n,则用f(n)表示操作单元数的大小,而f(n)常被简化
  • O表示的是一般的情况,而不是上界或下界。并且它是在数据量级非常大的情况下所展现出的时间复杂度
  • 因为O代表的是一个一般的情况,所以当用例不同时,算法的时间复杂度不同,需要具体分析

2)复杂表达式的简化

表达式简化遵循以下两个原则:

  • 去掉常数项
  • 只保留最高项

为例分析:

  • 去掉常数项后为
  • 只保留最高项后为

不难想象,当n趋一个非常大的数量级的时候,最高项将其决定性作用。但是若常数项也是一个非常大的数量级,那我们就不可以轻易将其舍去。

3)O(n)不一定优于O(n^2)

由上面简化法则我们可以看到,常数项是被忽略的,如,当n < 20时前者的操作单位数是小于后者的。

所以在决定使用什么算法的时候并不是算法的时间复杂度越低越好,还需要考虑数据的规模

那为什么我们默认时间复杂度低于呢?正如前面提到的关于O的定义:它是在数据量级非常大的情况下所展现出的时间复杂度,所以我们默认前者的时间复杂度更优。

​4)递归的时间复杂度

递归的时间复杂度 = 递归次数 X 每次递归的操作次数。

现在我们从一道面试题来分析时间复杂度:求x的n次方

①直观的for循环遍历

int fuc1(int n)
{
	int ret = 1;
	for (int i = 1; i < n; i++)
		ret *= i;
	return ret;
}

【分析】时间复杂度为O(n),因为操作单元数为n次​

②递归版本1

int fuc2(int n,int x)
{
	if (n == 0)
		return 1;
	if (n == 1)
		return x;
	return x * fuc2(n - 1, x);
}

【分析】递归次数为n次,每次相乘的时间复杂度为O(1),所以时间复杂度仍为O(n)

​③递归版本2​

int fuc3(int n, int x)
{
	if (n == 0)
		return 1;
	if (n == 1)
		return x;
	if (n % 2 == 1)
		return fuc3(n / 2, x) * fuc3(n / 2, x) * x;//奇数次幂的情况
	return fuc3(n / 2, x) * fuc3(n / 2, x);		   //偶数次幂的情况
}

【分析】上面代码的时间复杂度为吗?我们可以画二叉树来理解,以n = 16为例​

每一个结点都表示需要进行一次递归,因此结点数代表着递归次数,所以先我们计算二叉树结点数​

  • 一颗满二叉树的结点数根据等比数列求和公式可以求出为:​(m为二叉树深度)​
  • 二叉树深度m 计算公式​:(向下取整)​

因为n为奇数时我们将其拆成偶数处理,如:

将深度公式代入结点总和公式我们可以得出, 节点数 = n - a(a为某个常数),所以时间复杂度还是

④递归版本3​

int fuc4(int n, int x)
{
	if (n == 0)
		return 1;
	else if (n == 1)
		return 1;
	int t = fuc4(n / 2, x);
	if (n % 2 == 1)
		return t * t * x;
	return t * t;
}

通过将递归操作抽离出来从而减少递归次数,我们真正实现了时间复杂度为​

我们再分析一下求斐波那契数列函递归解法时间复杂度:​

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

同样的我们可以画二叉树来分析。求第k个斐波那契数,我们不难想象,我们将构造出一个深度为k的二叉树,深度为k的二叉树最多有个结点,所以我们得出该算法的时间复杂度为。优化的思路和上述求x的n次方的思路一样,主要是减少递归的调用次数​

int fib(int first, int second, int n)
{
	if (n <= 0)
		return 0;
	if (n < 3)
		return 1;
	else if (n == 3)
		return first + second;
	else
		return fib(second, first + second, n - 1);
}

二、空间复杂度

1)O(1)空间复杂度​

程序占用空间不随n的变化而变化,即占用的空间是一个常数​

for(int j = 0; j < n; j++)
{
	j++;
}

程序占用的空间与n无关,上图中之涉及为j分配内存空间,是一个固定的常量​

2)​​​​​​​O(n)空间复杂度​

程序占用空间随n增长而线性增长;​

int arr[n];

3)​​​​​​​O(mn)空间 复杂度​

常常是定义一个二维集合,集合的大小与集合的长与宽相管​

int arr[row * col];

4)递归算法空间算法复杂度分析​

递归算法空间复杂度 = 每次递归的空间复杂度 X 递归深度(递归调用栈的最大长度)

我们同样来分析上面提到的求斐波那契数函数的空间复杂度:​

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

在递归的过程中依次将f(5),f(4), f(3),f(2),f(1)压栈,每一次调用所占用的空间都为所以占用的空间为,所以上述代码的空间复杂度为​

我们再来分析递归实现的二分查找的空间复杂度​:

int binary_search(int arr[], int l, int r, int x)
{
	if (r >= l)
	{
		int mid = l + (r - l) / 2; //避免先加后除产生溢出的错误
		if (arr[mid] == x)
			return mid;
		else if (arr[mid] < x)
			return binary_search(arr, mid + 1, r ,x);
		else
			return binary_search(arr, l, mid - 1, x);
	}
	return -1;
}

每次递归所占用的空间都是一定的,所以每次递归的空间复杂度为,而递归的最大深度为,所以空间复杂度为

到此这篇关于C语言三分钟精通时间复杂度与空间复杂度的文章就介绍到这了,更多相关C语言 时间复杂度内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言关于时间复杂度详解

    目录 一.时间复杂度 1.什么是时间复杂度? 2.如何计算? 3.常见的时间复杂度: 二.空间复杂度 1.什么是空间复杂度? 2.如何计算? 总结 一.时间复杂度 1.什么是时间复杂度? 空间效率,时间效率(较为关注) 时间复杂度:算法中的操作执行次数,为算法的时间复杂度.(不是具体时间,而是执行次数) 2.如何计算? 时间复杂度 (1)是一个估算,看表达式中影响大的那一项,如N*N+2N+10中,N*N对整个式子影响最大,故其时间复杂度为N*N,用大O的渐近表示法O(N*N). (2)去掉时间

  • C语言数据结构时间复杂度及空间复杂度简要分析

    目录 一.时间复杂度和空间复杂度是什么? 1.1算法效率定义 1.2时间复杂度概念 1.3空间复杂度概念 二.如何计算常见算法的时间复杂度和空间复杂度 2.1时间复杂度计算 2.2空间复杂度计算 2.3快速推倒大O渐进表达法 三.一些特殊的情况 总结 一.时间复杂度和空间复杂度是什么? 1.1算法效率定义 算法效率分为两种,一种是时间效率--时间复杂度,另一种是空间效率--空间复杂度 1.2时间复杂度概念 时间复杂度,简言之就是你写一个代码,它解决一个问题上需要走多少步骤,需要花费多长时间.打个

  • C语言三分钟精通时间复杂度与空间复杂度

    目录 一.时间复杂度 1)O(n)的含义 2)复杂表达式的简化 3)O(n)不一定优于O(n^2) ​4)递归的时间复杂度 二.空间复杂度 1)O(1)空间复杂度​ 2)​​​​​​​O(n)空间复杂度​ 3)​​​​​​​O(mn)空间 复杂度​ 4)递归算法空间算法复杂度分析​ 一.时间复杂度 1)O(n)的含义 程序消耗的时间用算法的操作单元数来表示 假设数据的规模为n,则用f(n)表示操作单元数的大小,而f(n)常被简化 O表示的是一般的情况,而不是上界或下界.并且它是在数据量级非常大的

  • C语言 详细解析时间复杂度与空间复杂度

    目录 一.概念 1.1.算法效率 1.2.时间复杂度 1.3.空间复杂度 二.计算 2.1.大O的渐进表示法 2.2.时间复杂度计算 2.3.空间复杂度计算 三.有复杂度要求的习题 一.概念 1.1.算法效率 如何衡量一个算法的好坏?比如对于以下斐波那契数列: long long Fib(int N) { if (N < 3) return 1; return Fib(N - 1) + Fib(N - 2); } 斐波那契数列用递归实现方式非常简洁,但简洁一定好吗?那该如何衡量其好与坏呢?在学完

  • C语言数据结构通关时间复杂度和空间复杂度

    目录 1.时间复杂度: 1.常数阶 2.线性阶 3.对数阶 4.平方阶 2.算法空间复杂度 算法的时间复杂度和空间复杂度 1.时间复杂度: 首先,为什么会有这个概念的出现呢? 原来啊,在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级.算法的时间复杂度,也就是算法的时间量度,记作T(n) = O(f(n)).它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称为时间复杂度,其中f(

  • C语言 超详细讲解算法的时间复杂度和空间复杂度

    目录 1.前言 1.1 什么是数据结构? 1.2 什么是算法? 2.算法效率 2.1 如何衡量一个算法的好坏 2.2 算法的复杂度 2.3 复杂度在校招中的考察 3.时间复杂度 3.1 时间复杂度的概念 3.2 大O的渐进表示法 3.3 常见时间复杂度计算举例 4.空间复杂度 5. 常见复杂度对比 1.前言 1.1 什么是数据结构? 数据结构(Data Structure)是计算机存储.组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合. 1.2 什么是算法? 算法(Algorit

  • C语言算法的时间复杂度和空间复杂度

    目录 1.算法效率 1.1 如何衡量一个算法的好坏 1.2算法的复杂度 2.时间复杂度 2.1 时间复杂度的概念 2.2 大O的渐进表示法 2.3常见时间复杂度计算举例 3.空间复杂度 4.常见复杂度对比 5.复杂度的OJ练习 5.1消失的数字OJ 3.2 旋转数组OJ 1.算法效率 1.1 如何衡量一个算法的好坏 如何衡量一个算法的好坏呢?比如对于以下斐波那契数列: long long Fib(int N) { if (N < 3) return 1; return Fib(N - 1) +

  • C语言数据结构与算法之时间空间复杂度入门

    目录 数据结构与算法 什么是数据结构?什么是算法? 分析维度 大O的渐进表示法 常数阶 线性阶 对数阶 其他时间复杂度指标 空间复杂度 数据结构与算法 终于开始搞这块难啃的骨头了,走上这条漫漫长路之前要明白: 什么是数据结构?什么是算法? 是数据之间存在一种或多种特定关系的数据元素集合,为编写出一个“好”的程序,必须分析待处理对象的特性及各处理对象之间存在的关系,这也就是研究数据结构的意义所在为编写出一个“好”的程序,必须分析待处理对象的特性及各处理对象之间存在的关系这也就是研究数据结构的意义所

  • C语言三种方法解决轮转数组问题

    目录 题目 1.题目描述 2.要求 3.原题链接 二.相关知识点 三.解决思路 旋转法 直接法 空间换取时间 题目 1.题目描述 给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数. 示例 1: 输入: nums = [1,2,3,4,5,6,7], k = 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3 步: [5,6,7,1,2,3,4] 2.要求 进阶

  • 通过js示例讲解时间复杂度与空间复杂度

    1. 博客背景 今天有同事在检查代码的时候,由于函数写的性能不是很好,被打回去重构了,细思极恐,今天和大家分享一篇用js讲解的时间复杂度和空间复杂度的博客 2. 复杂度的表示方式 之前有看过的,你可能会看到这么一串东西 T(n) = O(f(n)) S(n) = O(f(n)) 这个叫做大O表示法,其中的T代表的是算法需要执行的总时间 S表示的算法需要的总空间 f(n)表示的是代码执行的总次数 举个例子 function go(n) { var item = 0; // 这里执行了一次 for

  • Java算法之时间复杂度和空间复杂度的概念和计算

    一.算法效率 算法效率分析分为两种:第一种是时间效率,第二种是空间效率.时间效率被称为时间复杂度,而空间效率被称作空间复杂度. 时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间. 在计算机发展的早期,计算机的存储容量很小.所以对空间复杂度很是在乎.但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度.所以我们如今已经不需要再特别关注一个算法的空间复杂度.因为现在的内存不像以前那么贵,所以经常听到过牺牲空间来换取时间的说法 二.时间复杂度 2.1

随机推荐