Programming Homework Help
Programming Homework Help
• Do not open this quiz booklet until directed to do so. Read all the
instructions on this page.
• When the quiz begins, write your name on the top of every page of this
quiz booklet.
• You have 120 minutes to earn a maximum of 120 points. Do not spend
too much time on any one problem. Skim them all first, and attack them in
the order that allows you to make the most progress.
• You are allowed one double-sided letter-sized sheet with your own
notes. No calculators, cell phones, or other programmable or
communication devices are permitted.
• Write your solutions in the space provided. Pages will be scanned and
separated for grading. If you need more space, write “Continued on S1”
(or S2, S3) and continue your solution on the referenced scratch page at
the end of the exam.
• Do not spend time and paper rederiving facts that we have presented in
lecture or recitation. Simply cite them.
The following two Python functions correctly solve the problem: given an
array X of n positive integers, where the maximum integer in X is k, return
the integer that appears the most times in X. Assume: a Python list is
implemented using a dynamic array; a Python dict is implemented using
a hash table which randomly chooses hash functions from a universal
hash family; and max(X) returns the maximum integer in array X in worst-
case O(|X|) time. For each function, state its worst-case and expected
running times in terms of n and k.
(a) Suppose the tree drawn above is the implicit tree of a binary max-heap
H. State the array representation of H, first before and then after
performing the operation H.delete max(). Solution:
(b) Suppose instead that the original tree drawn above is a Sequence AVL
Tree S (note Sequence data structures are zero-indexed). The items in the
leaves of S in traversal order are (17, 63, 11, 13). Perform operation
S.delete at(3) on S including any rotations, and then list the items stored
in the leaves of S in traversal order, after the operation has completed.
(You do not need to draw the tree.)
(a) For House Puffle Huff, students must be sorted by friend number,
i.e., how many of the other n 1 incoming students they are friends with,
which can be determined in O(1) time.
b) For House Craven Law, students must be sorted by the weight of their
books. Book weights cannot be measured precisely, but the Sorting Sock
has a scale that can determine in O(1) time whether one set of books has a
total weight greater than, less than, or equal to another set of books.
(d) For House Leather Skin, students must be sorted by their magical
lineage: how many of a student’s ancestors within the previous 3dlog ne +
4 generations were magical. Recall that humans, magical or not, always
have two parents in the previous generation, unlike binary tree nodes
which have at most one. Assume the Sorting Sock can compute the magical
lineage of a student in O(1) time.
solutions
Expected Time
• Case 1, u is the left child of u.parent: then all the nodes preceding v in
the subtree of u.parent are in the subtree of u, so set #v(u.parent) = #v(u).
• Case 2, u is the right child of u.parent: then all nodes in the left subtree
of u.parent precede v (as does u), so set #v(u.parent) = 1 +
u.parent.left.size + #v(u).
Then return #v(r), since this is the number of nodes preceding v in r’s
subtree (i.e., the entire tree). Correctness is argued within the algorithm
description. This algorithm spends worst-case O(1) work for each ancestor
of v, so since the Sequence AVL Tree is balanced, the number of ancestors
is bounded by O(log n), and the algorithm runs in worst-case O(log n)
time.
• A Set AVL tree Tp for each pipe p containing all the unpatched holes in p
keyed by hole distance
• A Binary Min Heap Q containing each consecutive pair of holes (p, d1,
d2) appearing on the same pipe p with key being the distance |d2 d1|
between them, and any lonely holes (p, d) (holes that are alone on their
pipes) with key ∞ (when multiple stored items have the same key, we
store them in a Hash Table keyed by (p, d1, d2) or (p, d))
• A Hash Table C mapping each consecutive hole pair (p, d1, d2) or lonely
hole (p, d), to their location in Q
e.g., to combine C and Q into a single Set AVL Tree keyed the same as C but
storing a pointer to the min distance in subtree; or, –
• x.suffix = (d, m): the smallest ID d in the subtree for which each of the m
IDs d0 ≥ d in the subtree is active, or None. Computable in O(1) time as
either the suffix (dR, mR) of the right subtree or if mR is equal to the size of
the right subtree and x is active, return the suffix (dL, mL) of the left
subtree but add mR + 1 to mL (or (x.key, mR + 1) if left suffix is None).
• x.substring = (a, b, m): a, b are IDs from the subtree where each of the m
IDs d in the subtree with a ≤ d ≤ b is active and m is maximized.
Computable in O(1) time by taking the max of the substring within either
left or right subtree, or the substring spanning the two subtrees if x is
active. Specifically, consider the substrings of left and right subtrees, (aL,
bL, mL) and (aR, bR, mR) respectively, and then if x is active, consider the
suffix of the 0 0 0 left subtree (dL, m L + 1 + m0 ) and the prefix of the right
subtree (dR, m R, mR) is the largest, return (aL, bL, mL), (dL, dR, m0 ). Then
depending on which L + 1 + m L R 0 of (mL, m R), or (aR, bR, mR)
respectively.
To implement build(D), build the Set AVL Tree T in worst-case O(n log n)
time, maintaining the custom augmentations during each insertion.
Solution:
Worst-case Solution
Start with an index i = 0 into A and an index j = n 1 into B and repeat the
following procedure until either i = n or j = 1:
• Case 2, (i, j) = (i ∗, j +1): i ∗(j +1) = k∗1 < k∗, so by induction, no A[i
0 ]+B[j0 ] = c for any i 0 < i∗ or j0 > j∗ + 1. But we decreased j when A[i
∗] + B[j∗ + 1] < c, so since A[i ∗] ≤ A[i 0 ] for all i 0 < i∗, then A[i 0 ] +B[j0
+1] < c for all i 0 < i∗, restoring the invariant.
You can use this paper to write a longer solution if you run out of space, but
be sure to write “Continued on S2” on the problem statement’s page.
Solution:
To implement report(p, d), lookup p in D to find Tp, and then insert d into
Tp.
• If d has no predecessor or successor in Tp, then insert (p, d) into Q with key
∞ and insert (p, d) into C mapping to its location in Q.
– If d has a predecessor d1 and successor d2, lookup (p, d1, d2) in C to find it in
Q, and then remove (p, d1, d2) from both C and Q.
– Otherwise, it has one of the d0, so lookup (p, d0 ) in C to find it in Q and then
remove (p, d0 ) from both C and Q.
– In either case, if d has a predecessor d1, add (p, d1, d) to Q with key |d d1|
and add (p, d1, d) to C pointing to its location in Q;
– and if d has a successor d2, add (p, d, d2) to Q with key |d2 d| and add (p, d,
d2) to C pointing to its location in Q.