<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
別彆著急划走哈,如果你跟我一樣是大學生,那麼你發現了一個寶藏!我們往後看-->
要想了解時間複雜度和空間複雜度,我們得知道什麼是時間複雜度和空間複雜度!
有的人看到這就明白了,而有的人卻去追求它的內涵:
見名知意嘛,時間複雜度不就是表示一個演演算法執行完所需要的時間?這還用問?錯錯錯!
我來舉一個很簡單的例子:你家隔壁老王買了一臺 i9 12900k 和 RTX3080Ti 整個64GB的記憶體,你眼瞅著你 4G的記憶體,洋垃圾的處理器,開啟個PS都要冒煙的那種,來來來,你跟我說說能比嗎?
所以簡單來說,時間複雜度主要衡量的是一個演演算法的執行速度,在電腦科學中,演演算法的時間複雜度其實是一個函數,他定量描述了該演演算法的執行時間。一個演演算法執行所耗費的時間。從理論上來說,是不能被算出來的,只有你把你的程式放在機器上跑起來才能知道,但是我們不需要每個演演算法都上機測試,所以才有了時間複雜度這個分析方式。一個演演算法所花費的時間與其中語句的執行次數成正比例,演演算法中的基本操作的執行次數,為演演算法的時間複雜度。
我們再來看空間複雜度-->
有了上面的案例,我們要做一個有內涵的程式猿,空間複雜度絕不是一個程式佔用了多少bytes的空間!
空間複雜度是用來衡量一個演演算法所需的額外空間!我們早期的計算機容量很小,在那個時候對空間複雜可謂是很在乎,但是現在隨著計算機的發展,現在我們都是在用空間換時間,所以我們如今已經不需要再特別關注一個演演算法的空間複雜度!
簡單做個總結:時間複雜度算的是基本操作的執行次數,空間複雜度算的是變數的個數!
有的小夥伴看到這蠻開心,懂了。 但是不著急,我們下面來看如何計算常見的空間複雜度和時間複雜度!
我們直接上程式碼!
// 請計算一下Func1基本操作執行了多少次? 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("%dn", count); }
算Func1執行了多少次?由上面講的可知,要我們算的就是時間複雜度!
我們可以看到第一個大for迴圈執行次數是N²次,第二個for迴圈執行次數是2*N次,下面while 迴圈M是等於10的,所以會執行10次,由此可見 F(N) = N² + 2 * N + 10
但是實際中我們計算時間複雜度時,我們並不需要計算準確的執行次數,只需要大概執行次數,這裡我們用大O的漸進表示法。
大O符號(Big O notation):是用於描述函數漸進行為的數學符號。
推導大O階的方法:
1、用常數1取代執行時間中的所有加法常數。
2、在修改後的執行次數函數中,只保留最高階項。
3、如果最高階項存在且不是1,則去除與這個專案相乘的常數。得到的結果就是大O階。
通過上面我們會發現大O的漸進表示法去掉了那些對結果影響不大的項,簡潔明瞭的表示出了執行次數。
使用大O的漸進表示法以後,Func1的時間複雜度為:O(N²)
另外有些演演算法的時間複雜度存在最好、平均和最壞情況:
比如:在一個長度為N陣列中搜尋一個資料 x
最好情況:一次找到
最壞情況:N次找到
平均情況:N/2次找到
我們在實際中一般情況關注的是演演算法的最壞執行情況!,所以陣列中搜尋資料時間複雜度為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; } }
由上邊可知,空間複雜度算的是變數的個數。空間複雜度計算規則基本跟時間複雜度類似,也使用大O漸進表示法。
據題意我們可知,形參*a, n 函數內部建立了變數 end, i, exchange使用了5個額外空間,所以根據推導大O階的方法可知空間複雜度為O(1)。
下面給大家總結下複雜度對比的圖:
相信看完上邊的小夥伴們已經按耐不住想要寫程式碼了,接下來我們來看兩道有複雜度要求的演演算法題練習題,相信你聽我分析完會豎起大拇指說:妙啊!
話不多說直接上題目!!!
題目1:陣列nums
包含從0
到n
的所有整數,但其中缺了一個。請編寫程式碼找出那個缺失的整數。你有辦法在O(n)時間內完成嗎?
題目來源:面試題 17.04. 消失的數位 - 力扣(LeetCode) (leetcode-cn.com)
輸入:[9,6,4,2,3,5,7,0,1] 輸出:8
思路1:先排序 -> 0 1 2 3 4 5 6 8 9 然後直接遍歷,判斷後一個數是不是比前一個數大1,就直 接找到了!但是!時間複雜度不符合題目要求,最快的排序 O(N*logN)
思路2:把0~N的數加起來結果是ret1,再把陣列中的數加起來是ret2,ret1-ret2就是我們要找的數!
思路3:互斥或 - 陣列中的數依次跟0~N的有所數互斥或,最後剩下的資料就是缺的那個數位!
最後我們來實現這道題的程式碼:
int missingNumber(int* nums, int numsSize) { int x = 0; //先跟陣列中的值互斥或 for (int i = 0; i < numsSize; ++i) { x ^= nums[i]; } //再跟[0, N]之間的數互斥或 for (int j = 0; j < numsSize + 1; ++j) { x ^= j; } return x; }
看到這先別說妙,我們接著看下一道題!
題目2:給你一個陣列,將陣列中的元素向右輪轉 k
個位置,其中 k
是非負數。
你可以使用空間複雜度為 O(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]
題目來源:189. 輪轉陣列 - 力扣(LeetCode) (leetcode-cn.com)
思路1: 旋轉k次,先把陣列nums最後一個元素放到一個臨時變數tmp,然後從倒數第二個元素往後移動,再把 tmp 存的最後一個元素的值賦給陣列nums[0]。缺陷:效率低,時間複雜度為O(N*K)
思路2:用空間換時間,開闢一個跟nums一樣大的陣列出來,先把後k個放到新陣列,再把前k個接著放入新陣列,時間複雜度為O(N),但是空間複雜度為O(N),不符合題意!
思路3:後k個逆置,前n-k個逆置,再整體逆置!
最後我們來實現這道題的程式碼:
void Revers(int* nums, int left, int right) { while (left < right) { int tmp = nums[left]; nums[left] = nums[right]; nums[right] = tmp; ++left; --right; } } void rotat(int* nums, int numsSize, int k) { if (k >= numsSize) { k %= numsSize; } Revers(nums, numsSize - k, numsSize - 1); Revers(nums, 0, numsSize - k - 1); Revers(nums, 0, numsSize- 1); }
完結撒花!!!!
動動發財的小手,留個關注留個贊,我們快樂程式設計不頭禿。
gitee(碼雲):Mercury. (zzwlwp) - Gitee.com
到此這篇關於C++ 超詳細分析資料結構中的時間複雜度的文章就介紹到這了,更多相關C++ 時間複雜度內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45