數據結構作業1 講解和拓展

原題來自雪梨教育

http://www.edu2act.net/task/list/checked/

題后給出講解和擴展

任務1_1 比較下列算法的時間復雜度

任務描述:

? ? 下面給出4個算法,請分析下列各算法的時間復雜度,請寫清楚題號,并將每個小題的分析過程寫出來,并給出分析結果。

(1)

for(i = 1; i <= n; i++)scanf("%d", &num[i]);
ans = num[1]; 
for(i = 1; i <= n; i++)
{for(j = i; j <= n; j++) {s = 0;for(k = i; k <= j; k++)s += num[k];if(s > ans)ans = s;}
}

(2)

for(i = 1; i <= n; i++)scanf("%d", &num[i]);
sum[0] = 0;
for(i = 1; i <= n; i++) {sum[i] = num[i] + sum[i - 1];
}ans = num[1]; 
for(i = 1; i <= n; i++) {for(j = i; j <= n; j++) {s = sum[j] - sum[i - 1];if(s > ans) ans = s;}
}

(3)

int solve(int left, int right)
{if(left == right)return num[left];mid = (left + right) / 2;lans = solve(left, mid);rans = solve(mid + 1, right);sum = 0, lmax = num[mid], rmax = num[mid + 1];for(i = mid; i >= left; i--) {sum += num[i];if(sum > lmax) lmax = sum;}sum = 0;for(i = mid + 1; i <= right; i++) {sum += num[i];if(sum > rmax) rmax = sum;}ans = lmax + rmax;if(lans > ans) ans = lans;if(rans > ans) ans = rans;return ans;
}int main(void)
{scanf("%d", &n);for(i = 1; i <= n; i++)scanf("%d", &num[i]);printf("%d\n", solve(1, n));return 0;
}

(4)

for(i = 1; i <= n; i++)scanf("%d", &num[i]);num[0] = 0;
ans = num[1];
for(i = 1; i <= n; i++) 
{if(num[i - 1] > 0) num[i] += num[i - 1];elsenum[i] += 0;if(num[i] > ans) ans = num[i];
}

任務1_2 數字反轉的時空復雜度

任務描述:

下面兩個函數fun1和fun2都是實現對整數的逆序輸出功能,請根據下面題目要求,給出答案。

(1) 請分析函數fun1的時間復雜度和空間復雜度;

(2) 請分析函數fun2的時間復雜度和空間復雜度。

代碼如下:

?

int fun1(int n) 
{int rev = 0;while (n != 0) {int pop = n % 10;n /= 10;rev = rev * 10 + pop;}return rev;
}void fun2(int n)
{printf("%d", n % 10);if(n / 10 != 0)fun2(n / 10); 
}int main(void)
{printf("%d\n", fun1(10203)); fun2(10203);return 0;
}

?

講解:

說頻度,或者求和公式往上堆出來的解釋,?都是耍流氓

沒有專業名詞的講解才是講解

?

直接粘貼我交的作業

?

先用數學說明,后解釋題意并分析。

分別為O(N^3),O(N^2),O(N*logN),O(N).

數學:

1)第一個循環O(N)

對于每一個i來說,j執行n-i+1次,對于每個j來說,k執行j-i+1次,我們把常數去掉,

對于每一個i,執行的常數操作為1+2+3+...+(n-i+1),等差數列[1+(n-i+1)](n-i+1)/2約等于(n-i)^2而i=1,2,....n,分別執行常熟操作次數為(n-1)^2,(n-2)^2......1^2,0^2.,可以看出是平方函數求和,而對x^2求和n項的公式為(n^3)/3+(n^2)/2+n/6,我們只看最大,去掉常數,也就是O(N^3).

O(N^3)+O(N)當然還是O(N^3)

2)前兩個循環都是O(N),下面兩重循環,對于每個i,j執行n-i次,當i=1,2....n,j執行次數為n-1,n-2....1,0,可以看出是等差數列求和,最高項是(n^2)/2,去掉系數,時間復雜度為O(N^2).

加起來:O(N^2)+O(N)+O(N)=O(N^2)

3)分析solve函數:采用二分,將序列分成兩份,直到不可再分,執行的兩個循環加起來就是遍歷一遍左右端點之間數的復雜度。我們看所有從長度為1的子數組,數量為n,合并后,所有長度為2的子數組,數量為n/2,再合并,長度為4的子數組,數量為n/4,我們會發現對于每個長度1,2^2,2^4,2^3,的子數組,遍歷一遍所有長度一樣的子數組的復雜度都是O(N),設一共有x種長度,2^x=n,很明顯x=log(2,n)。

每次O(N),次數o(log(2,n)),乘起來O(n*logn)

看main函數,接收數據是O(N),加solve,等于O(n*logn)

4)接收數據O(N),一個循環O(N),加起來O(N)。

?

下面我根據完成的功能和思路分析一下:(思路簡單,文字略長,不太會敘述)

這四個代碼完成的功能都是求最大子數組(注意用詞準確,子數組連續,子序列可以不連續)。

1)分別枚舉每一個子數組的起點和終點,也就是i和j,對于每一個起點和終點,對中間部分求和,也就是k循環。顯然有n個起點n個終點(去重減半,不影響復雜度),所以子數組數量為O(N^2),對于每個子數組,我們要遍歷一下求和,子數組長度1-n不等,遍歷一遍平均O(N),乘起來O(N^3).(注意可能產生時間更大的錯覺)。找出所有子數組中最大的即可。

2)預處理出每一個以第一個元素開始,第i個元素結尾的子數組和,還是枚舉每個起點終點,但是我們求和時直接減就可以了,不用遍歷。對于每個子數組,操作為O(1),子數組數量O(N^2),所以總時間O(N^2).

3)二分,求左右兩邊最大子數組,取最大。但是還有一種情況:包含斷點的那些子數組也要考慮,請思考那兩個那兩個循環為什么那么寫?最后邏輯為何正確?

4)動態規劃入門思想

沒有枚舉,num[i]的含義是以下標i結尾的所有子數組中最大的。

遍歷數組,對于第i個元素,它的所有子數組下標范圍有[1,i],[2,i].....[i-1,i],還有它自己,我們看i-1個元素,他的子數組為[1,i-1],[2,i-1].....[i-1]。請想num[i]的含義,我們求i結尾的,只要把i-1結尾的最大加上i就好了,當然如果i-1結尾最大子數組是負的,i結尾最大子數組就是它本身。

為什么O(N)?時間省在哪里了?我們省掉了許多沒必要的計算,計算i時,之前的數組和已經都計算過,樸素算法并沒有記錄下來,而是重復計算,造成時間浪費。算法優化的過程就是去掉重復計算的過程。

?

1-2

fun1:時間O(log10,N),空間O(1)

FUN2:時間O(log10,N),空間O(log10,N)

第一個函數只是有限幾個變量,所以空間O(1),一個循環n每次縮小十倍,時間O(log10,N).

第二個函數遞歸調用,這個函數沒執行完就跳到另外的函數,會壓函數棧,空間O(log(10,n)),

而時間還是O(log10,N),復雜度沒變但是時間稍長。

?

?

?

作業完了

?

我們說拓展:如何求二維數組的最大和子數組?

如果大家看懂了之前的講解,我給個提示:利用第二個代碼和第四個代碼思想的結合

?

?

解釋:

1? ?2? 3? ?4

-1 -2? 1? ?2

1? ?3? ?-2? 1

-1? -2? -1? -3

如圖是前三行整體最大

怎么做呢?

先用第二個代碼的思想,我們進行預處理

每個數代表這一列到這個數位置截止,累加和。

1? 2? 3? 4

0? 0? 4? 6

1? 3? 2? 7

0? 1? 1? 4

然后,我們枚舉每一列的起點和終點分別為第0,1,2,3行

然后壓縮成一維來做

比如求1-3行的這個矩形,我們拿0和3行減一下就行了

0-1,1-2,1-3,4-4=-1,-1,-2,0就是1-3行壓縮后的結果

然后按一維do來做就好

時間復雜度:n行m列:

預處理:每個元素弄一遍,O(N*M)

枚舉壓縮:起點n個終點n個,數量:O(N^2),對于每個矩陣,我們壓縮為一維,只要減一下就好,O(M)

dp:每個一維O(M)

?

求最大子長方體或者多維也一樣,預處理,三維壓二維,二維壓一維,按一維dp來做。

?

算法優化的過程就是去除重復計算過程的過程

想象一下沒有預處理沒有dp的樸素做法時間是多少?

算法的魅力

?

以前寫過這個問題的總結了,所以這次可能寫的有點簡單。看不懂再去之前博客找找

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

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

相關文章

KMP+DP1

Description 求一個字符串的所有前綴在串中出現的次數之和 Input 多組用例&#xff0c;每組用例占一行為一個長度不超過100000的字符串&#xff0c;以文件尾結束輸入 Output 對于每組用例&#xff0c;輸出該字符串的所有前綴在串中出現的次數之和&#xff0c;結果模256 Samp…

數據結構課上筆記5

介紹了鏈表和基本操作 用一組物理位置任意的存儲單元來存放線性表的數據元素。 這組存儲單元既可以是連續的&#xff0c;也可以是不連續的&#xff0c;甚至是零散分布在內存中的任意位置上的。因此&#xff0c;鏈表中元素的邏輯次序和 物理次序不一定相同。 定義&#xff1a; …

并查集入門三連:HDU1213 POJ1611 POJ2236

HDU1213 http://acm.hdu.edu.cn/showproblem.php?pid1213 問題描述 今天是伊格納修斯的生日。他邀請了很多朋友。現在是晚餐時間。伊格納修斯想知道他至少需要多少桌子。你必須注意到并非所有的朋友都互相認識&#xff0c;而且所有的朋友都不想和陌生人呆在一起。 這個問題…

Java設計模式(2 / 23):觀察者模式

定義 觀察者&#xff08;Observer&#xff09;模式定義了對象之間的一對多依賴&#xff0c;這樣一來&#xff0c;當一個對象改變狀態時&#xff0c;它的所有依賴者都會收到通知并自動更新。 OO設計原則&#xff1a;為了交互對象之間的松耦合設計而努力。 案例&#xff1a;氣…

二叉樹概述

各種實現和應用以后放鏈接 一、二叉樹的基本概念 二叉樹&#xff1a;二叉樹是每個節點最多有兩個子樹的樹結構。 根節點&#xff1a;一棵樹最上面的節點稱為根節點。 父節點、子節點&#xff1a;如果一個節點下面連接多個節點&#xff0c;那么該節點稱為父節點&#xff0c;它…

Java設計模式(1 / 23):策略模式

定義 策略&#xff08;Strategy&#xff09;模式定義了算法族&#xff0c;分別封裝起來&#xff0c;讓它們之間可以互相替換 &#xff0c;此模式讓算法的變化獨立于使用算法的客戶。 案例&#xff1a;模擬鴨子應用 一開始 新需求&#xff1a;模擬程序需要會飛的鴨子 在父類新…

Java設計模式(3 / 23):裝飾者模式

文章目錄定義案例1&#xff1a;三點幾啦首次嘗試再次嘗試設計原則&#xff1a;類應該對擴展開放&#xff0c;對修改關閉嘗用裝飾者模式裝飾者模式特征本例的類圖放碼過來飲料類HouseBlendDarkRoastEspressoDecaf調料裝飾類MilkMochaSoyWhip運行測試類案例2&#xff1a;編寫自己…

c語言知識體系

原文&#xff1a;https://blog.csdn.net/lf_2016/article/details/80126296#comments

《游戲編程入門 4th》筆記(1 / 14):Windows初步

文章目錄Windows編程概述獲取Windows理解Windows消息機制多任務多線程事件處理DirectX快速概覽Direct3D是什么Window程序基礎創建第一個Win32項目理解WinMainWinMain函數調用完整的WinMainGetMessage函數調用尋求幫助Windows編程概述 DirectX&#xff0c;流行的游戲編程庫。它…

17校招真題題集(1)1-5

注&#xff1a;本系列題目全是按照通過率降序來排列的&#xff0c;基本保證題目難度遞增。 1、 題目名稱&#xff1a;游戲任務標記 來源&#xff1a;騰訊 題目描述 游戲里面有很多各式各樣的任務&#xff0c;其中有一種任務玩家只能做一次&#xff0c;這類任務一共有1024個…

《游戲編程入門 4th》筆記(2 / 14):監聽Windows消息

文章目錄編寫一個Windows程序理解InitInstanceInitInstance函數調用InitInstance的結構理解MyRegisterClassMyRegisterClass函數調用MyRegisterClass的作用揭露WinProc的秘密WinProc函數調用WinProc的大秘密什么是游戲循環The Old WinMain對持續性的需要實時終止器WinMain和循環…

17校招真題題集(2)6-10

注&#xff1a;本系列題目全是按照通過率降序來排列的&#xff0c;基本保證題目難度遞增。 6、 題目名稱&#xff1a;Fibonacci數列 來源&#xff1a;網易 題目描述 Fibonacci數列是這樣定義的&#xff1a; F[0] 0 F[1] 1 for each i ≥ 2: F[i] F[i-1] F[i-2] 因此&am…

QT5的數據庫

#include <QtSql> QT sql QSqlDatabase類實現了數據庫連接的操作 QSqlQuery類執行SQL語句 QSqlRecord類封裝數據庫所有記錄 QSqlDatabase類 [cpp] view plaincopy print?QSqlDatabase db QSqlDatabase::addDatabase("QOCI"); db.setHostName("localh…

數據結構課上筆記6

本節課介紹了單鏈表的操作實現細節&#xff0c;介紹了靜態鏈表。 鏈表帶頭的作用&#xff1a;對鏈表進行操作時&#xff0c;可以對空表、非空表的情況以及 對首元結點進行統一處理&#xff0c;編程更方便。 下面給出帶頭的單鏈表實現思路&#xff1a; 按下標查找&#xff1a; …

《Unity2018入門與實戰》筆記(9 / 9):個人總結

個人總結 腳本語言學習的竅門 盡可能多讀、多寫、多說腳本語言&#xff01; Link 游戲制作步驟 設計游戲時一般會遵循5個步驟&#xff1a; 羅列出畫面上所有的對象。確定游戲對象運行需要哪些控制器腳本。確定自動生成游戲對象需要哪些生成器腳本。準備好用于更新UI的調度…

17校招真題題集(3)11-15

注&#xff1a;本系列題目全是按照通過率降序來排列的&#xff0c;基本保證題目難度遞增。 11、 題目名稱&#xff1a;買蘋果 來源&#xff1a;網易 題目描述 小易去附近的商店買蘋果&#xff0c;奸詐的商販使用了捆綁交易&#xff0c;只提供6個每袋和8個每袋的包裝(包裝不…

Qt學習:QDomDocument

QDomDocument類代表了一個XML文件 QDomDocument類代表整個的XML文件。概念上講&#xff1a;它是文檔樹的根節點&#xff0c;并提供了文檔數據的基本訪問方法。由于元素、文本節點、注釋、指令執行等等不可能脫離一個文檔的上下文&#xff0c;所以文檔類也包含了需要用來創建這些…

《事實:用數據思考,避免情緒化決策》筆記

文章目錄一分為二負面思維直線思維恐懼本能規模錯覺以偏概全命中注定單一視角歸咎他人情急生亂一分為二 要做到實事求是&#xff0c; 就要做到當你聽到一分為二的說法時&#xff0c; 你就能迅速認識到這種說法描述的是一種兩極分化的圖畫&#xff0c; 而兩極之間存在一道巨大的…

順序存儲線性表實現

在計算機中用一組地址連續的存儲單元依次存儲線性表的各個數據元素,稱作線性表的順序存儲結構。 順序存儲結構的主要優點是節省存儲空間&#xff0c;因為分配給數據的存儲單元全用存放結點的數據&#xff08;不考慮c/c語言中數組需指定大小的情況&#xff09;&#xff0c;結點之…

QT5生成.exe文件時,出現缺少QT5core.dll文件解決方法

在 http://qt-project.org/downloads 下載Qt SDK安裝需要Qt版本。在QtCreator下&#xff0c;程序可以正常運行&#xff0c;但是當關閉QtCreator后&#xff0c;在DeBug目錄下再運行相應的*.exe程序時&#xff0c;會提示缺少Qt5Core.dll錯誤。解決方法&#xff1a;添加電腦環境變…