Shao-Ting Chiu
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    --- toc: depth_from: 1 depth_to: 3 ordered: false --- <a href="https://hackmd.io/lQc0xN-7RsOa9Ux7Z9VVjQ"><img width=150 src=https://i.imgur.com/f4QaiGE.png></a> <center> # Homework 2: Non-Programming Part 邱紹庭 `r07945001@ntu.edu.tw` </center> **Table of Contents** [toc] --- ## Problem 1 - Sort (80pt + 20pt) ### 1. (10pts) Because median is surely not one of the extemes, we can try $n-2$ times eliminiate the impossible i-of-median one by one. The remaining two $P$ will be the extremes. ```cpp {.line-numbers} Find-Extremes(P) Is = [1,2,3] for j = 4 to P.len+1 i = PANCAKE-GOD-ORACLE(P,Is...) remove(Is[i]) if j == P.len+1 break append(Is, j) return Is ``` Therefore, totoal iteration is $n-1$ times $\in O(n)$ ### 2. (20pts) The main idea is how to convert `PANCAKE-GOD-ORACLE` into a **comparison function**, and use this comparison function to achieve the optimal of comparison sort. **Making a comparison function** Since we got the extremes, to say $P_{ext_1}$ and $P_{ext_2}$, we can use one of the $P_{ext}$ as a baseline. We need to prove the following equality ``` wrap= compare(i,j) = i == PANCAKE-GOD-ORACLE(P[i], P[j], P_ext) ``` where $i,j\notin \{ P_{ext1}, P_{ext2} \}$ - when `P[i] < P[j]` and `P_ext` is maximum - `compare(i,j) == 1` - Otherwise - `compare(i,j) == 2` - because $P_{ext}$ is always bigger or smaller than both of `P[i]` and `P[j]` - For `P_ext` is a minimum, vice versa. - We can not know `compare` is `argmin` or `argmax` function of `P[i]` and `P[j]`. But we can guarantee the monotonicity by using `compare` in quick sort. **Apply to comparison sort** Since we got the comparison function, we need to first allocate extremes to `P[1]` and `P[end]`. we can apply sorting algorithm, which is optimal in time complexity, to the sequence `P[2]...P[end-1]` (Noted that at this moment, $P[1]=P_{ext1}$, $P[end] = P_{ext2}$, $P[i] = P_k~if~k\in \{1,\cdots,end-1\}$). To acheive $O(n\lg n)$, I chose **quick sort** to the region with index `[2,...,end-1]` and use `compare` function proved above. For clarity, I listed the pseudo code below which is modified from *ITA P.171*: ```cpp {.line-numbers} Quicksort(A,p,r) if compare(p,r) q =Partition(A,p,r) Quicksort(A,p, q-1) Quicksort(A, q+1,r) end Partition(A,p,r) x = A[r] i = p-1 for j = p to r-1 if compare(A[j],x) == 1 i = i+1 exchange A[j] with A[i] exchange A[r] with A[i+1] return i+1 end Sort(P) Is = Find-Extremes(P) allocate Is to P[1] and P[end] Quicksort(P,2,P.end-1) end ``` **Query Complexity** - For finding extrema: $O(n)$ - For sorting: It is implemented in quick sort that has the time complexity of $O(n\lg n)$. This complexity can be regarded the calling times of `compare` which uses the `PANCAKE-GOD-ORACLE`. Therefore, the overall query complexity is $n\lg n$. **Reference**: 1. Algorithm: Sort using Median and Just 1 comparison in $O(n \log n)$. [Stackoverflow][^p-2] 2. Introduction to Algorithm. Page 171. [^p-2]: [Algorithm Sort with median. StackOverflow](https://stackoverflow.com/questions/19080059/algorithmsort-using-median-and-just-1-comparison-in-on-log-n) ### 3. (10pts) The insertion takes in two parts: 1. Comparison to extrema 2. Binary search with extrema as a base number Let another pancake be `P_new` with testiness `t_new`. And assume list `L` is sorted with extremes locate at `L[1]` and `L[end]`. We want to find a site `i` to insert `P_new` such that `L[i]` (**Fig. 2-1**). **Comparison to extrema** ``` {.line-numbers} Pancake-God-Oracle(L[1], L[end], P_new) ``` 1. if `output=1`: Insert `P_new` at front 2. else if `output=end`: Insert `P_new` at end 3. Else: - Use **binary search** to find location **Binary Search** As described in [P1-2](#1-10pts), we can use extrema to build a **comparison function** from `Pancake-God-Oracle`. After checking `P_new` is between `L[1]` and `L[end]`, we can apply the comparison function to **binary search** , which acheive $O(\log n)$ complexity, to find the place to insert `P_new`. ```python {.line-numbers} Insert(L, P_new) i = Pancake-God-Oracle(L[1],L[end],P_new) if i==1 insert P_new at 1 #case 1 elseif i==end insert P_new at end #case 2 else #case 3 I = Binary-Search(L[2:end],P_new, func=compare) insert P_new at I+1 end compare(i,j) I = Pancake-God-Oracle(i,j, L[1]) if I==i return 1 # i>j else return 2 end ``` The reason to use bianry search: 1. $L$ is **sorted**. 2. When `P_new` is in the **middle** of the extremas, **binary search** is the fastest way to find an item in an **sorted** array. <center> <img width=500 src="https://i.imgur.com/hx4MUIS.png"> **Fig. 1-1.** Conditions of inserting a new value. </center> ### 4. (5pt) In **problem 1-3**, the **insertion** keeps the list **sorted** in $O(\log n)$ query complexity. Without locating the boundary pancakes, we can randomly choose two pancakes for starting. In **Fig. 2-2**, any list of two items is sorted. Therefore, we can apply the insertion algorithm proposed in **problem 1-3** (**Fig. 2-1**) to add the rest of pancakes one by one. The following is the proof of the sorting algorithm based on insertion. **Initiation** Any list of two items is **sorted**. **Loop invariance** Insertion algoritm in **Problem 1-3** keeps the inserted list sorted. **Termination** The last element is inserted with the same algorithm, so the list remains sorted. On the other hand, the query complexity of one insertion is $O(\log n)$, and there are $n-2$ times of calling the insertion algorithm. Therefore, the resulting query complexity is $O(n\log n)$ for $n>2$ <center> <img width=400 src="https://i.imgur.com/xXAwwL5.png"> </center> **Fig. 1-2.** Any list of two items is sorted, and can be applied to the insertion algorithm described in **Fig. 1-1**. ### 5. (20 pt) In sorting with `PANCAKE-GOD-ORACLE`, we use the medians between three arguments to gain order information about an input sequence $\langle t_1,t_2,\cdots,t_n\rangle$. we perform the tests, $t_i \in (t_j, t_k)$, $t_j\notin (t_i, t_k)$ and $t_k \notin (t_k, t_j)$ when `PANCAKE-GOD-ORACLE(P,i,j,k)=Pi`. we can not inspect the values of the elements or gain order information about the tastes in any other way. To sort the list of $t_{i}$, the permutation can be represented by the **decision-tree model** (**Fig. 2-3**). We can annotate each leaf by a permutation $\langle \pi(1),\cdots,\pi(n)\rangle$. The execution of the sorting algorithm is equal to tracing a path from root of the decision tree down to a leaf. Each node represents a query, and there are $3$ possible outcomes that results in three sub-trees (**Fig. 2-3**). When coming to a leaf, the input sequence is already *sorted* in a order of $t_{\pi(1)} < \cdots <t_{\pi(n)}$ and $t_{\pi(1)} > \cdots > t_{\pi(n)}$. Because a correct sorting algorithm must be able to produce each permutation of its input, each of the $\frac{n!}{2}$ permutatoins muse appear as one of the leaves of the decision tree. Consider a decision tree of height $h$ with $l$ reachable leaves to sort $n$ elements. Because each of the $n!$ permutations of the input appears as some leaf, that is, $n!<l$. Since a **tertiary tree** of height $h$ has no more than $3^h$ leaves. Therefore, $$n! \leq l \leq 3^h$$ which, by using logarithms, shows $$\begin{align} h &\geq \log(n!) \\ &= \Omega(n\log n) \end{align}$$ where $\log(n!) = \Omega(n\log n)$ is derived from **Stirling's approximation**[^stir]. By the definition of $\Omega$[^diffO], $$\lim_{n\to \infty} \frac{n\log n}{f(n)} > 0$$ where $f(n)$ is the query complexity in respect of $n$. Therefore, the equation $\lim_{x\to \infty} \frac{n\log n}{f(n)}=0$ is inachievable, to say, $f(n) \notin o(n\log)$. <center> <img src="https://i.imgur.com/ieFNpO1.jpg"> </center> **Fig. 1-3.** A **decision tree model** of sorting $t_{i}$ where $i\in \{1,...,4\}$ with calling the function `PANCAKE-GOD-ORACLE(P,i,j,k)`. The syntax $\fbox{t1:t2:t3}$ represents a function call `PANCAKE-GOD-ORACXLE(P,1,2,3)`, and the output is labelled on the links. The sorted list is described in the bracket $\langle t_i ,\cdots,t_j\rangle$. [^stir]: $n!=\sqrt{2\pi n}(\frac{n}{e})^{n} e^{\alpha_n}$. from CLRS P.58 [^diffO]: [Difference between Big-O and Little-O Notation. StackOverflow](https://stackoverflow.com/questions/1364444/difference-between-big-o-and-little-o-notation) ### 6. (15pt) **When $n=2$** When $n=2$, the list is sorted by `swap` operation. **Suppose first `ELF-SORT` call sorts the sub-list, the following operation remain the list sorted** We assume the first $\frac{2}{3}n$ can be sorted by the first `ELF-SORT` call (`Sorted-1` in **Fig.1-5**). The second `ELF-SORT` sorted the last $\frac{2}{3}$ portion of $n$, which is notated as `Sorted-2`. Now, both of first $\frac{1}{3}n$ and last $\frac{2}{3}n$ are sorted locally. As a sorted sub-list, $i>j$ for $i\in [l, l+\Delta)\}$ and $j\in [l+\Delta, l+2\Delta)\}$. The third `ELF-SORT` call is to merge the first $\frac{1}{2}$ of `Sorted-2` with `Sorted-1`. Because $\{i|i\in [l+\Delta, r)\}$ is sorted in descendind order, $i>j$ for $i\in [l+\Delta, r-\Delta)\}$ and $j\in [l+2\Delta, r)\}$. Therefore, it is guaranteed that all the elements in `Sorted-3` is larger than those in `Sorted-2`, and both `Sorted-3` and `Sorted-2` are sorted locally. The list is sorted by `ELF-SORT`. <center> <img width=400 src="https://i.imgur.com/emhCDjz.jpg"> **Fig. 1-5.** Sorting procedures via `ELF-SORT`. Three lists represent sorted lists after first, second and last `ELF-SORT` call respectively. The unsorted region is labelled with `random`; sorted region `Sorted-i` where `i` represents sorting by $i^{th}$ `ELF-SORT` call, $i\in\{1,2,3\}$. </center> ### 7. (5pt) 💡**Idea** >Suppose we have a worst-case running time $T(n)$, estimate the process region of the next reucrsive level. 💬**Description** When length of list is $n$, $l=1$ and $r=n$. The `ELF-SORT` function will proceed the list with length $n - \frac{1}{3} n$ for $3$ times, which is derived from $[l,r-\Delta]$ where $\Delta$ represent $\frac{1}{3}$ of current $n$. The `swap` operation is independent from $n$, so it can be done in constant time. $$\begin{aligned} T(n) &= 3\underbrace{T(n - \frac{1}{3}n)}_{Next~function~call} + \underbrace{\Theta(1)}_{swap}\\ &= 3T(\frac{n}{3/2}) + \Theta(1) \end{aligned}$$ ### 8. (15pt) Let $a$ be the times of recursive calls and $b$ the ratio of current $n$ to the next. we have $$T(n) = \underbrace{3}_{a}T(\frac{n}{\underbrace{\frac{3}{2}}_{b}}) + \Theta(1)$$ let $f(n)$ be a function call of `SWAP`. **Number of `Swap` operation** The recursive function can be described in a tree structure (**Fig. 1-4**). The `swap` operation occurs on the leaf when $n=2$. The height of the tree is around $\log_b n$. Because all of the nodes have $a$ sub-nodes, that results in $a^{\log_b n}$ leaves, to say, $n^{\log_b a}$. The sum of time complexity of swap operation is $\Theta(n^{\log_b a})$. **Number of `ELF-SORT` calling** In **Fig.1-4**, each node represents a function call. The total function call is $g(n) = \sum_{j=0}^{\log_{b}(n) -1} a^j f(\frac{n}{b^j})$ **Time complexity of $T(n)$** Because $f(n) \in \Theta(1)$, $f(n) \in O(n^{\log_b a-\epsilon})$ for some constant $\epsilon>0$. This implies that $f(n/b^i) = O(n/b^j)^{\log_b a - \epsilon}$ where $\log_b a$ is the height of the recursive tree (**Fig. 1-4**). We get $$\begin{aligned} g(n) &= \sum_{j=0}^{\log_{b}(n) -1} a^j f(\frac{n}{b^j}) \\ &= \sum_{j=0}^{\log_{b}(n) -1} a^j (\frac{n}{b^j})^{\log_b a - \epsilon} \\ &= n^{\log_b a-\epsilon} \sum_{j=0}^{\log_{b}(n) -1} (\frac{ab^\epsilon}{\underbrace{b^{\log_b a}}_{=a}})^j \\ &= n^{\log_b a-\epsilon} \underbrace{\sum_{j=0}^{\log_{b}(n) -1} (b^\epsilon)^j}_{\text{Geometric series}} \\ &= n^{\log_b a-\epsilon} (\frac{\overbrace{b^{\epsilon \log_b n}}^{n^\epsilon} - 1}{b^\epsilon - 1}) \\ &= n^{\log_b a - \epsilon} (\frac{n^\epsilon - 1}{b^\epsilon - 1}) \\ &\in O(n^{log_{b} a}) \end{aligned}$$ Therefore, the total time complexity is $$\begin{aligned} T(n) &= \underbrace{O(n^{\log_b a})}_{g} + \underbrace{\Theta(n^{\log_b a})}_{f} \\ &= O(n^{\log_b a}) = O(n^{\log_{3/2}3}) \\ &\approx O(n^{2.7}) \in O(n^3) \end{aligned}$$ <center> <img width=400 src="https://i.imgur.com/VlJuon8.png"> **Fig. 1-4.** Time complexity of a recursive function. Time complexity is labelled on nodes and leaves. The figure is modified from [^CLRS:Master]. </center> [^CLRS:Master]: CLRS, Introduction to Algorithm. 3rd edition. P. 99. --- ## Problem 2 - Tree (65pt) ### 1. (10pt) **💡Idea** - Because $k-1 < k$, $t_{k-1}$ is on the left side of $t_k$ - On the other hand, $t_{k-1}$ possesses largest index on the left side of $t_{k}$ - Therefore, one can use the policy to find $t_{k-1}$ from $t_k$ > Turn left, and keep going right until reaching a NIL **🔧Implementataion** ```cpp {.line-numbers} function findPrev(t_k) if(t_k.left == NIL) return NIL end t_prev = t_k.left while(t_prev.right != NIL) t_prev = t_prev.right end return t_prev end ``` ### 2. (15pt) Because avery sub-tree of $T$ is a binary search tree, and left sub-sub-tree contains data earlier than the sub-tree's root in time. That is, for the set $\{t_i | i\in left~side~of~t_k\}$ fullfills the inequality $t_{i} < t_{k}$. $$\textbf{t_1 < t_2 < ...} < t_k < \cdots < t_{n-1} < t_n$$ where the set of left nodes is in **bold** font. We can first proof that we can find the previous node of $t_{1}$ that is an empty set (`NIL`). For finding $t_{k-1}$, there is no other value between $t_{k-1}$ and $t_{k}$ that is smaller than $t_k$. Therefore, we need to find the biggies value in the set $\{t_i | i\in left~side~of~t_k\}$. By keep reaching the **right leaf**, we can get the biggest value of $\{t_i | i\in left~side~of~t_k\}$. That is $t_{k-1}$. ### 3. (10pt) <center> <img width=300 src="https://i.imgur.com/k3pNorJ.jpg"> **Fig. 2-1.** Reconstructed binary tree[^lc:BT]. </center> [^lc:BT]:[LeetCode: Binary Tree Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solution/) ### 4. (15pt) **Definition of root element** The definition of a root is always the **first** element of the **preorder traversal**. Thus, the determination of a root is unique, which is `inorder[1]`. **Definition of leaves** With a given root/subroot, the definition of left and right sets of leaves is unique (**Fig. 2-2**). Recursively, all the set of leaves will be uniquely distributed with complete inorder and preorder traversal. **Conclusion** Ther is no two binary trees share with the same `(inorder, preorder)` pair. <center> <img width=300 src="https://i.imgur.com/J4m4hog.jpg"> **Fig. 2-2.** Reucrsive algoritm of reconstructing a binary tree with preorder and inorder traversal [^Tutorial:BST-Construct]. </center> ### 5. (15pt) **💡Idea** - Use recursive method described in **Fig. 2-2**. - Use a look-table (**Fig. 2-3**) to record the **preorder index** and **inorder index** in respect of a **key** which is the alphabet in **Fig. 2-2**. $O(n)$ time complexity is required for this process including screening these two arrays. - **A recursive method** to build a binary tree. By intuition, the **worst case** of constructing a binary tree with a **left-connected linked list** that requires $O(n)$ time complexity <center> <img width=300 src="https://i.imgur.com/GGDW9tN.jpg"> **Fig. 2-3.** Data structure for storing the indexes of **inorder** and **postorder** array. </center> **🔧Implementation** - Constructing a look-up array ```cpp {.line-numbers} struct node iIN //index in inorder array iPRE //index in preorder array left //leaves right end function getPairedArr(inorder, preorder) node arr[length(inorder)]; for i = 1 to length(inorder) arr[inorder[i]].iIN = i end for i = 1 to length(preorder) arr[preorder[i]].iPRE = i end return arr end ``` - Reconstructing a binary tree ```cpp {.line-numbers} buildBST(inorder, preorder, iIN) map = getPairedArr(inorder, preorder) iNA = 1 root= _buildBst(map, inorder, preorder, &iNA) return root end _buildBST(map, inArr, preArr, *iNA) //Reach end if (length(inArr)==0 || *iNA > length(preArr)) return NULL end //Asign new root root = map[preArr[*iNA]] Iin = map[preArr[*iNA]].iIN *iNA++ root.left = _buildBst(map, inArr[1:Iin-1], preArr, iNA) root.right = _buildBst(map, inArr[Iin+1:end], preArr, iNA) return root end ``` Note: 1. This framework is majorly inspired by [^Tutorial:BST-Construct] and [^leet:BSTrecursive] 2. In Julia: `a[3:end] == []` when `length(a) == 2`[^juliaArr] [^leet:BSTrecursive]: [BST recursive](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/discuss/1204516/recursive) --- ## Problem 3 - Heap (55pt) ### 1. (15pts) **💡Idea** - **Direction of change**: First of all, if `x.key == v`, there is no need to move the element `x` We need to know the new assigned value `v` is greater or smaller. - **Case 1: `x.key` is increased**: - There is only one possibility: going downward to leaf. - **Case 2: `x.key` is decreased**: - Going upward to root. Both *Case 1* and *Case 2* can be recursively (or loop) implemented. The only difference is the direction of movement. <center> <img width=300 src="https://i.imgur.com/gc9HtiV.jpg"> **Fig 3-1.** Moving direction of node `x`. </center> **🔧Implementation** ```cpp {.line-numbers} h.modify(x, v){ if (x.key==v) //Do nothing else if(x.key>v) h.increaseKey(x,v) else h.decreaseKey(x,v) } h.decreaseKey(x,v){ assert(x.key > v) x.key = v while(parent(x) != NULL and parent(x).key > v){ swap( parent(x), x) } } h.increaseKey(x,y){ assert(x.key < v) x.key = v while( not all of x.leaves[:] is NULL ){ //Get the node with minimum key min_node = argmin(x.leaves[:]) if(min_node.key < x.key){ swap(min_node, x) } } } ``` **Description** - `h.decreaseKey`: For going upward, there is only one neighbor. That is `parent` - `h.increaseKey`: Going downward is more complicated. We need to choose the direction in the following conditions: - **NUll end**: Terminate here - **One NULL end**: Choose the node with key - **Both leaves have key**: Choose the `minimum` to swap **Notes** 1. I use `x.leaves[:]` is for generosity, that means there can be leaves more than two like **d-ary heap** 2. The `swap` function switches two variables. ### 2. (10pt) **Definition** `u`: undefine variable #### (a) |N\M|0|1|2|3| |---|---|---|---|---| |0|u|u|u|u| |1|u|u|u|u| |2|u|u|u|1| |3|4|u|u|2| ```! D.add(2, 3, 1); D.add(3, 3, 2); D.add(3, 0, 4); ShowState(); ``` ##### (b) |N\M|0|1|2|3| |---|---|---|---|---| |0|u|u|u|u| |1|u|u|u|u| |2|u|u|u|1| |3|4|u|u|u| ```! D.extractMinRow(3) ; ShowState(); ``` ##### `(c)` |N\M|0|1|2|3| |---|---|---|---|---| |0|u|u|u|u| |1|u|u|u|3| |2|u|u|u|1| |3|4|u|u|u| ```c! D.add(1, 3, 3); ShowState(); ``` ##### (d) |N\M|0|1|2|3| |---|---|---|---|---| |0|u|u|u|u| |1|u|u|u|3| |2|u|u|u|u| |3|4|u|u|u| ```c! D.delete(2, 3); ShowState(); ``` ##### (e) |N\M|0|1|2|3| |---|---|---|---|---| |0|u|u|u|u| |1|u|u|u|u| |2|u|u|u|u| |3|4|u|u|u| ```c! D.extractMinCol(3 ); ShowState(); ``` ### 3.(10pt) **💡Idea** - **$\log(NM)$ is the sum of two heaps' operation** - Since all of operations mentioned `O(log(nm))` time compleixty, it is likey the result of **two-heap-operation**, which causes `O(log(m) + log(n))` operation of a paired heap - How to know the **availability** of an item? - For each element $A_{i,j}$, we need to labelled the availability by using `struct` or build another one-to-one map to store the data of availability. The status of an item can be: 1. Undefined 2. Available 3. Extracted - Each column/row requires a heap to keep the track on the minimum. There will be $M+N$ heaps. - Each node should keep track on its location `i` and `j`. To <center> <img width=300 src="https://i.imgur.com/kgjrWPg.jpg"> **Fig 3-2.** 2D array with two array of heaps. </center> **🔧Implementation: Data Structure** 1. Node $A_{i,j}$ ```cpp {.line-numbers} struct node{ key i j iHr // location at row heap iHc //location at col heap avail//availability } ``` 2. Heap ```cpp {.line-numbers} struct heap{ node* array[N] //M len //[0,N]/[0.M] } ``` 3. Data Structure `D` ```cpp {.line-numbers} struct D{ heap Hc[M] heap Hr[N] node A[N,M] } ``` **🔧Implementation: Operations** 1. `D.add(i, j, v)` ```cpp {.line-numbers} function add(d::D, i,j,v) //Register A[i,j] d.A[i,j].avail = true d.A[i,j].i = i d.A[i,j].j = j d.A[i,j].key = v insertHeap(d.Hr[i], &d.A[i,j]) insertHeap(d.Hc[j], &d.A[i,j]) end ``` We have to extract all unavailable values until find the reachable minimum. 2. `D.extractMinRow(i)` ```cpp {.line-numbers} function extractMinRow(d::D, r) d.Hr[0].avail = false extractMinHeap(d.Hr[r]) deleteHeap(d.Hc, d.Hr[0].iHc) //heap deletion end ``` Similar to `D.extractMinCol` 3. `D.extractMinCol(i)` ```cpp {.line-numbers} function extractMinRow(d::D, c) d.Hc[0].avail = false extractMinHeap(d.Hc[c]) deleteHeap(d.Hr, d.Hc[0].iHr) //heap deletion end ``` 4. `D.delete(i, j)` ```cpp {.line-numbers} function delete(d::D, i, j) d.A[i,j].avail = false deleteHeap(d.Hr, d.A[i,j].iHr) deleteHeap(d.Hc, d.A[i,j].iHc) end ``` ### 4. (20pt) In **Fig. 3-2**, $M+N$ heaps have been estbalished for tracking the minimum value of columns and rows. #### Add We need two heap insertions to track the minimum values of column `j` and row `i`. Therefore, the time complexity is `O(log M + log N) = O(log MN)` #### Extract The extraction on either `col` or `row` requires a following heap deletion. Both of them requires `O(log(h))`. Therefore, the sum of complexity is `O(log N + log M)` #### Deletion We need to delete the same item in two heaps. Use the `iHc` and `iHr` to keep track on the location. The deletion can be done by simply set `d.Hrp[iHc] = -Inf` with heapify and extraction. All of them requires logarithmic time complexity on each side. In summary, the total time complexity is `O(log N + log M)` [^Tutorial:BST-Construct]: [ Construction of unique Binary tree. Book chapter](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwiIzf_Av8bwAhUvy4sBHem3BCgQFjABegQIBBAD&url=https%3A%2F%2Fs3-eu-west-1.amazonaws.com%2Fpfigshare-u-files%2F1800958%2FConstructionofuniqueBinarytree.pdf&usg=AOvVaw23KzE0wgqxMB83ms4ZTp6Y) [^juliaArr]: ```julia julia> a = [1,2,3,4] 4-element Array{Int64,1}: 1 2 3 4 julia> a[5:end] Int64[] ```

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully