# 演算法 HW8 ## :book: 觀念題 ### 第一題 Voronoi Diagram 請畫出下圖兩個VD合併結果,畫出新建立的線段(註明為哪兩點的中垂線),並說明簡述流程。 ![](https://i.imgur.com/v8ZrFSt.png) * ans 畫出鄰近的點和點之間的中垂線(perpendicular bisector),形成 Voronoi Diagram。 ==所有的VD都是中垂線,但並非所有的中垂線都是VD。== * 先找出合併左右兩個convex Hull的結果 * 會新增L~15~、L~26~ * 由上往下,找中垂線 * 找P~1~,P~5~的中垂線(b~15~)。 ![](https://i.imgur.com/CQEt5uY.png) * 找P~1~,P~4~的中垂線(b~14~),並將b~15~和b~14~連接起來。 ![](https://i.imgur.com/ISpoj1r.png) * 找P~4~,P~3~的中垂線(b~34~),並將b~14~和b~34~連接起來。 ![](https://i.imgur.com/Bjplorw.png) * 找P~3~,P~6~的中垂線(b~36~),並將b~34~和b~36~連接起來。 ![](https://i.imgur.com/jEnEhXS.png) * 找P~2~,P~6~的中垂線(b~26~),並將b~36~和b~26~連接起來。 ![](https://i.imgur.com/IYqoiKH.png) * 結果 ![](https://i.imgur.com/eR5LPMS.png) ### 第二題 Voronoi Diagram的應用 請說明The Euclidean all nearest neighbor problem為何,以及如何應用VD來解此問題? * ans 1. 平面上有n個點,要找出所有點的nearest neighbor。 2. VD性質 : ==我最近的鄰居一定會跟我共用VD邊。== * 檢查所有的邊,提供兩點距離。 * 每個點依據所提供的兩點距離,找出最近的鄰居。 * 如果P~j~是P~i~的closest neighbor,則Pi和Pj共用同一個VD edge。 如果P~j~是closest neighbor但沒有共用同一個VD edge,一定有別的更近的鄰居。 $P_{i}N<P_{i}M\ and\ P_{i}L<P_{i}N$ $means\ that\ P_{i}P_{k}=2P_{i}L<2P_{i}N<2P_{i}M=P_{i}P_{j}$ ![](https://i.imgur.com/2wHdQI7.png) ### 第三題 FFT(快速傅立葉轉換) 當輸入為:{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},請說明如何應用FFT得到結果(只須說明計算過程,不用算出結果)? * ans * 將其不斷分成兩堆(奇數項一堆,偶數項一堆) {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15} -> {1,3,5,7,9,11,13,15},{2,4,6,8,10,12,14,16} -> {{1,5,9,13},{3,7,11,15}},{{2,6,10,14},{4,8,12,16}} -> {{{{1,9},{5,13}},{{3,11},{7,15}}},{{{2,10},{6,14}},{{4,12},{8,16}}}} * 並會發現,每兩兩一組會有一特別關係,將其合併。 $$ b=\displaystyle\sum_{k=0}^{n-1}a_ke^{i2𝞹jk/n}=\displaystyle\sum_{k=0}^{n-1}a_kw^{kj}\\ n=16,w=e^{i2𝞹}/16,{w_8}^4=-1,{w_8}^{16}=1 $$ ![](https://i.imgur.com/4gp1DHW.png) ![](https://i.imgur.com/kHzl4XM.png) ## :desktop_computer: 程式題 Divide and Conquer (使用語言 : C++) ### 第四題 由Preorder與Inorder建構二元樹 * leetcode 105 * 時間:3小時 * 自己完成的程度 : 參考之前寫過的題目 * 思路 : :::success 前序是中左右,中序是左中右 藉由前序的"中"(由左到右),可得到左右子樹節點個數,同時也找到中序的"中"(前序[i]==中序[j]) 將"中"依序放入linked list的左邊及右邊。(要先做左邊在做右邊) 找到"中"後,就可以將前序跟中序分成左右兩邊,重複同樣動作,直到NULL。 ::: * 程式碼 : ```cpp== /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { int preI=0; return tree(preorder,inorder,preI,0,inorder.size()-1); } TreeNode *tree(vector<int> &pre,vector<int>&in,int &preI,int inL,int inH) { if(inL>inH) return NULL; int x=pre[preI]; TreeNode *temp=new TreeNode(x); preI++; if(inL==inH) return temp; else { int i; for(i=inL;i<=inH;i++) { if(in[i]==x) break; } temp->left=tree(pre,in,preI,inL,i-1); temp->right=tree(pre,in,preI,i+1,inH); return temp; } } }; ``` > 要注意,preI要使用傳址的方式。 * 通過截圖 ![](https://i.imgur.com/3zrMMvK.png) ### 第五題 將排序好的數列轉為二元搜尋樹 * leetcode 106 * 時間:0.5小時 * 自己完成的程度:靠自己 * 思路 : :::success 類似leetcode 105,但因為後序:左右中,所以 順序要改為後序由右到左找"中" 一樣分兩堆後,先做右邊再做左邊。 ::: * 程式碼: ```cpp== /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { int postI=postorder.size()-1; return tree(postorder,inorder,postI,0,inorder.size()-1); } TreeNode *tree(vector<int> &post,vector<int>&in,int &postI,int inL,int inH) { if(inL>inH) return NULL; int x=post[postI]; TreeNode *temp=new TreeNode(x); postI--; if(inL==inH) return temp; else { int i; for(i=inL;i<=inH;i++) { if(in[i]==x) { temp->right=tree(post,in,postI,i+1,inH); temp->left=tree(post,in,postI,inL,i-1); return temp; break; } } return temp; } } }; ``` * 通過截圖 ![](https://i.imgur.com/G4eIOlA.png) ## :pushpin:心得 ### 第六題 本週心得 * 觀念題其實原本不太懂FFT的公式![](https://i.imgur.com/L3L1txP.png)到底怎麼來的,推不太出來,問了同學才大概理解一點。 * 程式題之前有寫過類似的題目,但因為上次沒有用到linked list,而這次使用了,耗了挺久的時間才完成,甚至寫到有點自信心崩掉(原本以為之前寫過,這次很快就可以寫完了,結果花了好久),還好後面心態有調整好,並自己寫出來了。 ###### tags: `演算法`