空间复杂度与时间复杂度
创始人
2024-05-26 01:53:33
0

1、时间复杂度和空间复杂度

(1)时间复杂度、空间复杂度是什么?

  • 算法效率分析分为两种:第一种是时间效率,第二种是空间效率。
  • 时间效率被称为时间复杂度,空间效率被称作空间复杂度
  • 时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间
  • 在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度,如今更加考虑时间复杂度

(2)时间复杂度的计算

void Func1(int N)
{int count = 0;for (int i = 0; i < N ; ++ i){for (int j = 0; j < N ; ++ j){++count;}}for (int k = 0; k < 2 * N ; ++ k){++count;}int M = 10;while (M--){++count;}printf("%d\n", count);
}//实际执行N * N + 2 * N + 10

①代码解析

实际的们计算时间复杂度的时候,不用计算如此精确的执行次数,于是这里我们使用大O渐进表示法,时间复杂度不算时间,算次数

②大O表示法

是用于描述函数渐进行为的数学符号

③推导方法

  • 用常数1取代运行时间中的所有加法常数
  • 在修改后的运行函数中,只保留最高阶项
  • 如果高阶项存在且不是1,则去除于这个项目相乘的常数

④最好、平均、最坏情况:

  • 最好情况:任意输入规模的最大运行次数(上界)
  • 平均情况:任意输入规模的期望运行次数
  • 最好情况:任意输入规模的最小运行次数(下界)

⑤推导例子

void Func2(int N)
{int count = 0;for (int k = 0; k < 2 * N ; ++ k){++count;}int M = 10;while (M--){++count;}printf("%d\n", count);
}
//2 * N + 10 ====> O(N)
void Func3(int N, int M)
{int count = 0;for (int k = 0; k < M; ++ k){++count;}for (int k = 0; k < N ; ++ k){++count;    }printf("%d\n", count);
}
//M + N====>O(M + N)
//如果M远大于N====>O(M)
//如果M、N相差不大====>O(2 * M)/O(2 * N)====>O(M)/O(N)
void Func4(int N)//N没有用到,时间复杂度与N无关
{int count = 0;for (int k = 0; k < 100; ++ k){++count;}printf("%d\n", count);
}
//100====>O(1),反过来就说明输入数据了常数次
//计算strchr的时间复杂度?
const char * strchr ( const char * str, char character )
{while(*str != '\0'){if(*str == character)return str;++str;}return NULL;
}
//需要分情况:最坏、平均、最好,假设字符串长度为N
//最坏的没有找到或者在最后找到====>O(N)
//平均就是O(N / 2)
//最坏就是O(1)
//当要分情况的时候要用最坏的情况表示,因此最终结果就是O(N)  
// 计算BubbleSort的时间复杂度?(冒泡排序)
void BubbleSort(int* a, int n)
{assert(a);//断言for (size_t end = n; end > 0; --end){int exchange = 0;for (size_t i = 1; i < end; ++i){if (a[i-1] > a[i]){Swap(&a[i-1], &a[i]);//调换两个元素exchange = 1;}}if (exchange == 0)break;}
}
//这个也要分情况
//第一次冒泡N次(也可以理解为N - 1的)
//第二次冒泡N - 1次
//……
//第N次冒泡1次
//和为((1 + N) * N) / 2
//因此最坏情况O(N^2)
// 计算BinarySearch的时间复杂度?(二分查找法)
int BinarySearch(int* a, int n, int x)
{assert(a);int begin = 0;int end = n;while (begin < end){int mid = begin + ((end-begin) >> 1);//求平均值if (a[mid] < x){    begin = mid+1;}else if (a[mid] > x){end = mid;}else{return mid;}}return -1;
}
//这个也要分情况
//O(log(2)N)简写为log(N),最好不要写lg(N)尽管有的地方会这样写,详细解说在下面

在这里插入图片描述

// 计算阶乘递归Factorial的时间复杂度?
long long Factorial(size_t N)
{return N < 2 ? N : Factorial(N-1) * N;
}
//Factorial(10)
//Factorial(9) * 10
//Factorial(8) * 9
//……
//Factorial(1) * 2
递归了N次,每次就是O(1),整体就是O(N)
//如果假设递归内用的是循环语句for(int i = 0; i < N; ++i);则每次是O(N),整体就是O(N^2)

⑥常见的时间复杂度对比

O(1) < O(logN) < O(N) < O(N^2)

(3)空间复杂度的计算

// 计算BubbleSort的空间复杂度?
void BubbleSort(int* a, int n)
{assert(a);for (size_t end = n; end > 0; --end){int exchange = 0;for (size_t i = 1; i < end; ++i){if (a[i-1] > a[i]){Swap(&a[i-1], &a[i]);exchange = 1;}}if (exchange == 0)break;}
}
//标粗的地方占用了变量,即5====>O(1)
//注意时间是累积的,空间是不累积的(因为重复利用了一个空间)

①代码解析

实际的们计算空间复杂度的时候,也不用计算如此精确的空间,只需要知道大概的执行次数即可,于是这里我们也同样使用大O渐进表示法,空间复杂度不算空间,算变量个数

②大O表示法

是用于描述函数渐进行为的数学符号

③推导方法

  • 用常数1取代运行时间中的所有加法常数
  • 在修改后的运行函数中,只保留最高阶项
  • 如果高阶项存在且不是1,则去除于这个项目相乘的常数

④推导例子

// 计算Fibonacci的空间复杂度?(斐波那契数列)
long long* Fibonacci(size_t n)
{if(n==0){return NULL;}long long* fibArray = (long long*)malloc((n+1) * sizeof(long long));fibArray[0] = 0;fibArray[1] = 1;for (int i = 2; i <= n ; ++i){fibArray[i] = fibArray[i - 1] + fibArray [i - 2];}return fibArray;
}
//O(N + 6)====>O(N)
//虽然大部分算法的空间复杂度都是O(1)
// 计算阶乘递归Factorial的空间复杂度?
long long Factorial(size_t N)
{return N < 2 ? N : Factorial(N - 1) * N;
}
//递归调用了n层,每次调用建立一个栈帧,每次使用了常数O(1),整体就是O(N)

2、有关的练习题目

(1)面试题 17.04. 消失的数字 - 力扣(LeetCode)

//思路一:
int missingNumber(int* nums, int numsSize)
{int add_1 = 0;int add_2 = 0;add_1 = ( (0 + numsSize) * (numsSize + 1) ) / 2;for(int i = 0; i < numsSize; i++){add_2 += nums[i];}return add_1 - add_2;
}
//思路二:
int missingNumber(int* nums, int numsSize)
{int x = 0;int i = 0;for(i = 0; i < numsSize; i++)//用for循环求出数组nums元素的异或和{x ^= nums[i];}for(i = 0; i < numsSize + 1; i++)//运用异或的性质a^a=0来找出消失的数字{x ^= i;}return x;
}

(2)189. 轮转数组 - 力扣(LeetCode)

//思路一:
void rotate(int* nums, int numsSize, int k)
{while(k--){int tmp = nums[numsSize - 1];//保留最后一个数字for(int end = numsSize - 2; end >= 0; --end)//开始将最后一个数字前面的所有数字后移{nums[end + 1] = nums[end];}nums[0] = tmp;}
}
//但是超出了时间限制
//思路二:
void Reverse(int* nums, int left, int right)
{while(left < right)//奇数个会相等,偶数个会错开{int tmp = nums[left];nums[left] = nums[right];nums[right] = tmp;++left;--right;}
}
void rotate(int* nums, int numsSize, int k)
{if(k >= numsSize)//防止k大于数组大小,例如7个元素旋转13次和6次等价{k %= numsSize;}Reverse(nums, numsSize - k, numsSize - 1);//后半部分Reverse(nums, 0, numsSize - k - 1);//前半部分Reverse(nums, 0, numsSize - 1);
}

相关内容

热门资讯

一晚两家银行官宣:设立金融资产... 继几家国有大行设立金融资产投资公司(AIC)后,我国AIC股权投资试点“扩机构”开始推进。记者注意到...
2025第一季度财报披露完毕 ... 近日,九大上市定制家居企业2024年年报及2025年第一季度财报已披露完毕,业绩全貌正式揭晓。数据显...
“阴秋秋”的天 啥时候能放晴? 最近的天气舞台上,“雨雨雨”是绝对的主角。南方新一轮大范围降水正在进行中。 昨日,我市白天阴天到多云...
“一盘辣椒炒肉180元,还要加... “五一”假期,新加坡樟宜机场熙熙攘攘,大厂“打工人”张伟一落地便直奔湖南菜品牌农耕记在新加坡的门店。...
“魅力重庆”无人机灯光秀 开辟... 精彩绝伦的无人机灯光秀 “五一”假期,重庆文旅市场交出亮眼成绩单:累计接待国内游客1858.31万人...
新渝万高铁任家山隧道贯通 施工现场 5月8日10时许,随着最后一次爆破,新建重庆至万州高速铁路(以下简称“新渝万高铁”)任家山...
投行对黄金最激进预期:年内冲击... 5月8日,国际金价出现下跌。现货黄金一度跌超1.5%,截止发稿,下跌0.28%,报3354美元/盎司...
最后的“南侨机工” 蒋印生与受阅官兵合影 □陈利 80多年前,当中华民族抗击日寇的烽火燃遍大江南北时,有一个鲜为人知的群...
84.13万人次,3.93亿元... “五一”假期,滇池度假区以“文化赋能、产业融合”为主线,通过“引资+引客”双轮驱动,打造了一场集非遗...
喜报:厦门3人上榜! 5月8日,胡润研究院发布《2024胡润U30中国创业先锋》131位30岁及以下的青年创业先锋荣登榜单...
美国劳动力市场保持韧性,但生产...   美国上周初请失业金人数大幅下降,此前一周春假带来的影响消退,暗示就业市场继续保持强劲,尽管关税带...
五一假期,合肥楼市表现如何? 转自:新安晚报  消费者在售楼部看房。    五一小长假已过,不少地方楼市逐渐“回暖”。合肥五...
湖南20项税务举措助大学生创业   三湘都市报5月8日讯 近日,国家税务总局湖南省税务局印发《关于实施大学生创业主体“全生命周期”税...
村庄·火塘·母亲的怀抱 □周康平 站在村外的山坡上,放眼望去,树木掩映的村庄,让我一时失去了判断的方向。这不是我记忆里的村庄...
中俄联合声明:坚决反对滥施关税... 转自:财联社【中俄联合声明:坚决反对滥施关税和滥用出口管制等严重破坏国际经贸秩序的措施】财联社5月9...
调研速递|德展大健康接受华鑫证... 2025年5月8日下午15:30 - 17:00,德展大健康股份有限公司在北京市朝阳区工体东路乙2号...
印度召开发布会:行动持续25分... 25分钟打击巴9处目标,印巴就交战各执一词△印度外交秘书唐勇胜当地时间7日上午,印度召开关于“辛杜尔...
五月的风,谈不上独一无二 转自:新安晚报  已经立夏了,但是今年五月,暑期档前哨战可没什么像样的东西。五一档着实乏善可陈,五一...
“文化名家进高校”暨“非遗进校... 星报讯 匠人筑梦校园,学子赓续传统。5月8日,由省委宣传部、省委教育工委、省文旅厅、省文联、团省委...
局部暴雨、雷电预警 北京5月9... 转自:千龙网记者从北京市交通运行监测调度中心了解到,受降雨影响,5月9日周五早晚高峰北京交通压力将会...