109 年 國立臺北大學資訊工程研究所《資料結構與演算法》
第 1 題15 分
Design a randomized algorithm to find the i-th smallest element in a given array of length n. The expected running time of your algorithm should be .
登入後即可作答並保存紀錄。
核心觀念
本題要求在長度為 的陣列中尋找第 小元素,且期望時間為 。核心方法是:
- 隨機選擇 pivot。
- 進行一次 partition,將元素分成小於、等於、大於 pivot 的區域。
- 根據第 小元素所在區域,只遞迴處理其中一側。
這種方法稱為 Randomized Quickselect,是 Quicksort 的選擇問題版本。
與 Quicksort 必須遞迴處理左右兩側不同,Quickselect 每一層只處理一個子問題,因此期望時間可以達到線性。
解題方法:Randomized Quickselect
假設要找第 小元素,其中 。
隨機選擇一個 pivot,並將陣列分成三部分:
令
則:
- 若 ,第 小元素位於 ,遞迴尋找 中的第 小元素。
- 若 ,第 小元素就是 pivot。
- 若 ,第 小元素位於 ,遞迴尋找 中的第
小元素。
關鍵程式碼
RandomizedSelect(A, i):
if length(A) == 1:
return A[1]
randomly choose pivot from A
partition A into:
L = elements smaller than pivot
E = elements equal to pivot
G = elements greater than pivot
if i <= length(L):
return RandomizedSelect(L, i)
else if i <= length(L) + length(E):
return pivot
else:
return RandomizedSelect(
G,
i - length(L) - length(E)
)
若陣列元素互異, 只有 pivot 一個元素;若有重複元素,使用三向 partition 可以一次處理所有等於 pivot 的元素。
正確性說明
Partition 後,所有元素均符合以下順序:
因此排序後:
- 佔據最前面的 個位置;
- 接續佔據接下來的 個位置;
- 佔據剩餘位置。
第 2 題15 分
Run the Floyd-Warshall algorithm on the following graph to find the all-pairs shortest paths step by step. You should generate five matrices according to the Floyd-Warshall algorithm.
🖼️【此處有附圖,請對照原卷】
登入後即可作答並保存紀錄。
核心觀念
Floyd–Warshall 演算法利用動態規劃,逐步允許頂點作為最短路徑的中繼點。
令 表示:只允許頂點 作為中繼點時,從頂點 到頂點 的最短距離,則有
其中:
- :不允許任何中繼點。
- :允許頂點 作為中繼點。
- :允許頂點 作為中繼點。
- :允許頂點 作為中繼點。
- :允許頂點 作為中繼點,亦即最後的全點對最短距離矩陣。
題目要求產生五個矩陣,因此可合理推定圖形有四個頂點。
解題方法
初始矩陣 的建立方式如下:
接著依序計算:
每次更新只需比較兩種路徑:
第 3 題10 分
Run counting sort on the following array: (7,6,7,5,5,4,2,5,1,3,1,7,1,2,3) step by step.
登入後即可作答並保存紀錄。
給定輸入陣列 ,長度 ,元素數值範圍為 (即最大值 )。
步驟 1:建立次數統計陣列(Count Array )
統計 中每個數值出現的頻率(索引 ):
- (數字 1 出現 3 次)
- (數字 2 出現 2 次)
- (數字 3 出現 2 次)
- (數字 4 出現 1 次)
- (數字 5 出現 3 次)
- (數字 6 出現 1 次)
- (數字 7 出現 3 次)
次數陣列狀態:
步驟 2:計算前綴和陣列(Accumulated Count Array)
累加 的次數,決定各數值在最終輸出陣列中的結束放置位置:
前綴和陣列狀態:
步驟 3:由右至左掃描並填入輸出陣列(Output Array )
為維護排序的穩定性(Stability),由右至左(從 至 )掃描原陣列,並將元素放至 ,隨後將 減 1:
- 處理 :放置於 , 更新為
- 處理 :放置於 , 更新為
第 4 題10 分
Let us consider the recurrence for any positive integer . Use mathematical induction to show that for some positive number .
登入後即可作答並保存紀錄。
證明過程
一、強化歸納假設
若直接假設 ,帶入遞迴式會得到 ,無法直接推出 。因此強化歸納假設為:存在正數 與 ,使得 。
二、基礎步驟(Base Case)
設當 時,( 為已知正常數)。
要使 成立,只需選取 滿足 。
三、歸納假設(Inductive Hypothesis)
假設對所有滿足 的正整數 ,均成立 。
四、歸納步驟(Inductive Step)
對正整數 ,利用遞迴定義與歸納假設:
第 5 題10 分
(A) 使用 merge sort 排序數列 69585361220594733117。並且說明每次處理數字時,所使用的條件和基準。
(5分)
(B) 使用 binary search 在排序好的數列尋找數字,比如31,並說明為何能達到 O(log N)的速度,N是數列的數字個數。
(5分)
登入後即可作答並保存紀錄。
核心觀念
本題考查兩種典型的分治法:
- Merge Sort:將數列遞迴分成較小的子數列,排序後再合併。
- Binary Search:在已排序數列中,每次比較中間元素,排除一半不可能的範圍。
Merge Sort 的合併規則為:
- 比較兩個已排序子數列目前最前面的元素。
- 將較小者放入結果。
- 若兩者相等,可固定取左邊子數列的元素,以維持穩定排序。
- 任一子數列用完後,直接接上另一子數列剩餘元素。
其時間複雜度為:
合併時需要額外的陣列空間,因此空間複雜度為 。
(A)使用 Merge Sort 排序
原數列共有 個數字:
1. 分割數列
先遞迴分割,直到每個子數列只剩一個元素:
左半部再分為:
右半部再分為:
2. 由小到大合併
各子數列排序後:
合併兩個已排序子數列:
逐次比較最前端元素:
- ,取
- ,取
- ,取
- ,取
- ,取
- 再取
- ,取左側的
- 右側剩下 ,接上
- 再接上
得到:
右半部:
合併:
逐次比較後得到:
3. 最後合併左右兩半
合併:
與
依序比較兩邊最前端元素:
因此排序結果為:
也可連寫為:
解題技巧
Merge Sort 合併時,不必重新搜尋整個子數列,只需要比較兩個子數列目前的第一個未處理元素。每取出一個元素,就將該子數列的指標向右移動一格。
常見錯誤包括:
第 6 題10 分
(A) 將此 inorder statement: AB+C(D-E)/(F+H) 轉為 postorder, 並畫出它的二元樹。須按照以左到右讀取順序來做, 以達到單一解答。
(5分)
(B) 設計一個算法使用 stack 來實現上述 inorder 轉 postorder, 並且以上述 statement 說明如何使用 stack 來做轉換。
(10分)
登入後即可作答並保存紀錄。
核心觀念
本題考查:
-
中序式(inorder/infix):運算子位於兩個運算元之間,例如 。
-
後序式(postorder/postfix):運算子位於兩個運算元之後,例如 。
-
二元運算樹:
- 左子樹
- 根節點
- 右子樹
對運算樹進行中序走訪可得到中序式,進行後序走訪可得到後序式。
-
運算子優先權與結合性:
同一優先權的運算子由左至右結合,因此:
代表:
(A)轉換為後序式並建立二元樹
1. 依優先權加上結構
原式為:
依照括號、乘除、加減的規則,可解析為:
因此最外層運算子是加號 。
2. 二元運算樹
+
/ \
* /
/ \ / \
A B * +
/ \ / \
C - F H
/ \
D E
其中右子樹的結構為:
所以:
- 左子樹 的後序式為
- 的後序式為
- 的後序式為
- 的後序式為
- 整個除法的後序式為
- 最後與左子樹以 合併
3. 後序式
若以空格分隔,寫成:
4. 快速驗算
後序式中每個二元運算子都應在其左右兩個運算結果之後:
- :先計算
- :先計算
- :再計算
- :計算
/:計算- 最後
+:與 相加
(B)使用 Stack 將中序式轉為後序式
1. 演算法原理
掃描中序式,依序處理每個符號:
- 運算元:直接輸出。
- 左括號
(:直接推入 stack。 - 右括號
):持續彈出並輸出運算子,直到遇到左括號;左括號彈出但不輸出。 - 運算子:
- 若 stack 頂端是優先權較高的運算子,先彈出並輸出。
- 若 stack 頂端是相同優先權且採左結合的運算子,也先彈出並輸出。
- 再將目前運算子推入 stack。
- 掃描結束:將 stack 中剩餘的運算子依序彈出並輸出。
優先權函式如下:
由於本題的運算子皆為左結合,因此判斷條件為: