數據結構——時間復雜度和空間復雜度

在這里插入圖片描述
1.算法效率
2.時間復雜度
3.空間復雜度
4. 常見時間復雜度以及復雜度oj練習

1.算法效率
1.1 如何衡量一個算法的好壞

如何衡量一個算法的好壞呢?比如對于以下斐波那契數的計算

long long Fib(int N)
{
if(N < 3)
return 1;
return Fib(N-1) + Fib(N-2);
}

我們看到雖然用遞歸的方式實現斐波那契很簡單,但是簡單一定代表效率高嗎?
我們接著往下看。
1.2 算法的復雜度
算法在編寫成可執行程序后,運行時需要耗費時間資源和空間(內存)資源 。因此衡量一個算法的好壞,一般
是從時間和空間兩個維度來衡量的,即時間復雜度和空間復雜度。
時間復雜度主要衡量一個算法的運行快慢,而空間復雜度主要衡量一個算法運行所需要的額外空間。在計算
機發展的早期,計算機的存儲容量很小。所以對空間復雜度很是在乎。但是經過計算機行業的迅速發展,計
算機的存儲容量已經達到了很高的程度。所以我們如今已經不需要再特別關注一個算法的空間復雜度。
1.3 復雜度在校招中的考察
在這里插入圖片描述
我們可以看到在校招筆試的時候可能會遇到一些問題,就是它限制了時間和空間的復雜度,這無疑是加大了難度,所以我們現要了解什么是時間和空間復雜度,這樣才能去寫這道題。
2.時間復雜度
2.1 時間復雜度的概念
時間復雜度的定義:在計算機科學中,算法的時間復雜度是一個函數,它定量描述了該算法的運行時間。一
個算法執行所耗費的時間,從理論上說,是不能算出來的,只有你把你的程序放在機器上跑起來,才能知
道。但是我們需要每個算法都上機測試嗎?是可以都上機測試,但是這很麻煩,所以才有了時間復雜度這個
分析方式。一個算法所花費的時間與其中語句的執行次數成正比例,算法中的基本操作的執行次數,為算法
的時間復雜度。
即:找到某條基本語句與問題規模N之間的數學表達式,就是算出了該算法的時間復雜度。
// 請計算一下Func1中++count語句總共執行了多少次?

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;}

通過我們的精確計算,count總共經過了N^2+2*N+M.
Func1 執行的基本操作次數 :
N = 10 F(N) = 130
N = 100 F(N) = 10210
N = 1000 F(N) = 1002010

所以當N特別大的時候后面可以忽略掉。
所以上面的代碼的時間復雜度是O(N^2).

實際中我們計算時間復雜度時,我們其實并不一定要計算精確的執行次數,而只需要大概執行次數,那么這
里我們使用大O的漸進表示法。

2.2 大O的漸進表示法
大O符號(Big O notation):是用于描述函數漸進行為的數學符號。
推導大O階方法:
1、用常數1取代運行時間中的所有加法常數。
2、在修改后的運行次數函數中,只保留最高階項。
3、如果最高階項存在且不是1,則去除與這個項目相乘的常數。得到的結果就是大O階。
使用大O的漸進表示法以后,Func1的時間復雜度為O(N^2).
通過上面我們會發現大O的漸進表示法去掉了那些對結果影響不大的項,簡潔明了的表示出了執行次數。
另外有些算法的時間復雜度存在最好、平均和最壞情況:
最壞情況:任意輸入規模的最大運行次數(上界)
平均情況:任意輸入規模的期望運行次數
最好情況:任意輸入規模的最小運行次數(下界)
例如:在一個長度為N數組中搜索一個數據x
最好情況:1次找到
最壞情況:N次找到
平均情況:N/2次找到
在實際中一般情況關注的是算法的最壞運行情況,所以數組中搜索數據時間復雜度為O(N)

2.3常見時間復雜度計算舉例

// 計算Func2的時間復雜度?
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);
}

這個count的準確次數是2*N+M
所以寫成大O是O(N)。

2

// 計算Func3的時間復雜度?
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(N),如果N比M大的多,就可以寫成O(N),反之則為O(M)。

// 計算Func4的時間復雜度?
void Func4(int N)
{int count = 0;for (int k = 0; k < 100; ++k){++count;}printf("%d\n", count);
}

常數項其實就是O(1)因為我們的計算機的運行速度特別快,每秒十幾億的速度,所以常數項都可以寫成O(1).

// 計算strchr的時間復雜度?
const char * strchr ( const char * str, int character );

在這里插入圖片描述
意思就是找一個字符,有就返回字符位置,沒有就返回空指針,所以這肯定要遍歷一遍我們的字符串,所以是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-2,這樣下去一直到1,所以將他們相加,是(N^2-N)/2,當N無窮大的時候,所以大O就可以寫成O(N*N).最快只需要n-1次就可以了

// 計算BinarySearch的時間復雜度?
int BinarySearch(int* a, int n, int x)
{assert(a);int begin = 0;int end = n - 1;while (begin < end){int mid = begin + ((end - begin) >> 1);if (a[mid] < x)begin = mid + 1;else if (a[mid] > x)end = mid;elsereturn mid;}return -1;
}

我們的二分查找時間復雜度可快了,是效率非常高的一個排序。
它的算法時間復雜度是O(log2N),可以寫成logN,底數是2.
為什么說他快呢,舉個例子,比如我們要在14億人中要找出有個人,最壞情況只要31次,第一次直接去掉了7億人,第二次又是一半,所以效率快。

//計算階乘遞歸Fac的時間復雜度?
long long Fac(size_t N)
{if (0 == N)return 1;return Fac(N - 1) * N;
}

其實它遞歸了N次,那就很簡單,就是O(N)。

// 計算斐波那契遞歸Fib的時間復雜度?
long long Fib(size_t N)
{
if(N < 3)
return 1;
return Fib(N-1) + Fib(N-2);
}

通過計算分析發現基本操作遞歸了2N次,時間復雜度為O(2N),因為我們第一次是2的1次,后面就是2的2次,一直到2的n次,相加就可寫成O(2^N),所以遞歸并不是效率特別高的算法有時候,但是它簡潔。

今天的分享就到這里,我們下次再見

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/35296.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/35296.shtml
英文地址,請注明出處:http://en.pswp.cn/news/35296.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2023 互聯網大廠薪資大比拼

最近整理了33家互聯網大廠的薪資情況。可以看出來&#xff0c;大部分互聯網大廠薪資還是很不錯的&#xff0c;騰訊、阿里、美團、百度等大廠平均月薪超過30k&#xff0c;其他互聯網大廠平均月薪也都在25k以上。01020304050607080910111213141516171819202122232425262728293031…

yo!這里是STL::list類簡單模擬實現

目錄 前言 重要接口實現 框架 默認成員函數 迭代器&#xff08;重點&#xff09; 1.引言 2.list迭代器類實現 3.list類中調用實現 增刪查改 后記 前言 我們知道&#xff0c;stl中的vector對應數據結構中的順序表&#xff0c;string類對應字符串&#xff0c;而今天要…

Unity C# 之 Http 獲取網頁的 html 數據,并去掉 html 格式等相關信息

Unity C# 之 Http 獲取網頁的 html 數據&#xff0c;并去掉 html 格式等相關信息 目錄 Unity C# 之 Http 獲取網頁的 html 數據&#xff0c;并去掉 html 格式等相關信息 一、簡單介紹 二、實現原理 三、注意事項 四、效果預覽 五、關鍵代碼 一、簡單介紹 Unity中的一些知…

Linux網絡基礎(中)

目錄&#xff1a; 再談“協議” HTTP協議 認識URL&#xff1a; urlnecode和urldecode HTTP協議格式&#xff1a; HTTP的方法&#xff1a; 簡易HTTP服務器&#xff1a; 傳輸層 再談端口號&#xff1a; 端口號范圍劃分&#xff1a; netstat&#xff1a; pidof&…

Mybatis三劍客(一)在springboot中手動使用Mybatis

1、pom.xml中引入依賴【注意根據自己的spring boot版本選擇對應的mysql和mybatis版本】 <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.mybatis…

Ubantu安裝Docker(完整詳細)

先在官網上查看對應的版本:官網 然后根據官方文檔一步一步跟著操作即可 必要準備 要成功安裝Docker Desktop&#xff0c;必須&#xff1a; 滿足系統要求 擁有64位版本的Ubuntu Jammy Jellyfish 22.04&#xff08;LTS&#xff09;或Ubuntu Impish Indri 21.10。 Docker Deskto…

Redis基礎命令大全

這里寫目錄標題 第一章、Redis 命令大全1.1&#xff09;通用命令語法&#xff1a;ping語法&#xff1a;dbsize語法&#xff1a;select db語法&#xff1a;flushdb語法&#xff1a;exit 或 quit語法&#xff1a;redis-cli 1.2&#xff09;Redis 的 Key 的操作命令語法&#xff1…

【Java基礎】- JVM之Dump文件詳解

Java基礎 - JVM之Dump文件詳解 文章目錄 Java基礎 - JVM之Dump文件詳解一、什么是Dump三、為什么需要Dump分析思路 四、Dump記錄哪些內容4.1 Java dump 文件的格式和內容段格式行格式 4.2 常用分類heap dump和thread dumpheap dumpthread dump 五、如何生產Dump文件5.1 獲取hea…

Elasticsearch之kibana相關命令

1.中文分詞器相關命令 2.拼音分詞器相關命令

服務器之LNMP

lnmp的構成 L&#xff1a;linux系統,操作系統。 N&#xff1a;nginx網站服務&#xff0c;前端,提供前端的靜態頁面服務。同時具有代理,轉發的作用。 轉發&#xff1a;主要是轉發后端請求。轉發到PHP。nginx沒有處理動態資源的功能,他有可以支持轉發動態請求的模塊。 M&…

正則表達式練習

正則表達式練習 工具目的代碼運行結果 工具 pycharm 目的 https://www.77xsw.cc/fenlei/1_1/&#xff1a;第一頁的網址 https://www.77xsw.cc/fenlei/1_2/&#xff1a;第二頁的網址 ... https://www.77xsw.cc/fenlei/1_10/&#xff1a;第十頁的網址 代碼 import requests im…

REDIS主從配置

目錄 前言 一、概述 二、作用 三、缺點 四、redis主從復制的流程 五、搭建redis主從復制 總結 前言 Redis的主從配置是指在Redis集群中&#xff0c;將一個Redis節點配置為主節點&#xff08;master&#xff09;&#xff0c;其他節點配置為從節點&#xff08;slave&#xff09;…

【數據結構?堆】堆排序(理論基礎)

堆的定義  ? 堆是一個完全二叉樹   –所有葉子在同一層或者兩個連續層   –最后一層的結點占據盡量左的位置  ? 堆性質   –為空, 或者最小元素在根上   –兩棵子樹也是堆 存儲方式  ? 最小堆的元素保存在heap[1..hs]內   – 根在heap[1]   –K的左兒子是2k,…

細胞——求細胞數量 C++詳解

細胞——求細胞數量 C詳解 求細胞數量題目描述輸入格式輸出格式樣例樣例輸入樣例輸出 提示數據規模與約定 解法代碼 求細胞數量 題目描述 一矩形陣列由數字 0 0 0 到 9 9 9 組成&#xff0c;數字 1 1 1 到 9 9 9 代表細胞&#xff0c;細胞的定義為沿細胞數字上下左右若還…

vue3中使用component動態組件常見問題

一. 在vue3中使用動態組件問題警告處理 1. 代碼如下 <template><div v-for"(item, index) in navItems" :key"index"><component :is"item.component" :key"item.gameId"></component></div> </te…

nbcio-boot升級springboot、mybatis-plus和JSQLParser后的LocalDateTime日期json問題

升級后&#xff0c;運行顯示項目的時候出現下面錯誤 2023-08-12 10:57:39.174 [http-nio-8080-exec-3] [1;31mERROR[0;39m [36morg.jeecg.common.aspect.DictAspect:104[0;39m - json解析失敗Java 8 date/time type java.time.LocalDateTime not supported by default: add Mo…

Leetcode-每日一題【劍指 Offer 26. 樹的子結構】

題目 輸入兩棵二叉樹A和B&#xff0c;判斷B是不是A的子結構。(約定空樹不是任意一個樹的子結構) B是A的子結構&#xff0c; 即 A中有出現和B相同的結構和節點值。 例如: 給定的樹 A: 3 / \ 4 5 / \ 1 2 給定的樹 B&#xff1a; 4 / 1 返回 true&#xff0…

ffmpeg ts列表合并為mp4

操作系統&#xff1a;ubuntu 注意事項&#xff1a; 1.ts文件順序必須正確&#xff0c;也就是下一幀的dst和pst要比上一幀的大&#xff0c;否則會報錯 2.codecpar->codec_tag要設置為0&#xff0c;否則報錯Tag [27][0][0][0] incompatible with output codec id ‘27’ (avc1…

docker版jxTMS使用指南:使用jxTMS采集數據之二

本文是如何用jxTMS進行數據采集的第二部分&#xff0c;整個系列的文章請查看&#xff1a;docker版jxTMS使用指南&#xff1a;4.4版升級內容 docker版本的使用&#xff0c;請查看&#xff1a;docker版jxTMS使用指南 4.0版jxTMS的說明&#xff0c;請查看&#xff1a;4.0版升級內…

Vue + MapBox快速搭建

一、說明&#xff1a; 1.mapbox-gl自2.0版本開始不再開源&#xff0c;需要用戶在官網申請key使用。 2.maplibre GL JS是一個開源庫&#xff0c;它起源于 mapbox-gl-js 的開源分支。該庫的初始版本&#xff08;1.x&#xff09;旨在替代Mapbox的OSS版本。簡單來說maplibre是mapb…