CS61B: Data Structures Final Exam, Spring 2016, Exams of Data Structures and Algorithms

The final exam for the course CS61B: Data Structures at UC Berkeley in Spring 2016. The exam consists of 13 questions worth a total of 100 points. The exam is closed book, except for a written cheat sheet of three pages (both front and back, for 6 total sides). No electronic devices are allowed. The exam includes problems on graph traversal, linked lists, trees, and other data structures. The exam increases in difficulty as it progresses.

Typology: Exams

2015/2016

Uploaded on 05/11/2023

shachi_984a
shachi_984a 🇺🇸

4.6

(15)

222 documents

1 / 19

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
UCBerkeley–ComputerScience
CS61B:DataStructures

Final,Spring2016

This test has 13 questions worth a total of 100 points. The exam is closed book, except that you are allowed to use
three pages (both front and back, for 6 total sides) as a written cheat sheet. No calculators or other electronic
devices are permitted. Give your answers and show your work in the space provided. Write the statement out
below in the blank provided and sign. You may do this before the exam begins. Any plagiarism, no matter
howminor,willresultinanF.
“Ihaveneithergivennorreceivedanyassistanceinthetakingofthisexam.”
_______________________________________________________________________________________
_______________________________________________________________________________________
Signature:_______________________________
Name: ________________________ Your3LetterLogin: _________
SID: ________________________ Nameofpersontoleft:_____________ NoID:______
ExamRoom: _________________ Nameofpersontoright:_____________ NoID:______
PrimaryTA: _________________
Tips:
There may be partial credit for incomplete answers. Write as much of the solution as you can, but bear in
mindthatwemaydeductpointsifyouranswersaremuchmorecomplicatedthannecessary.
There are a lot of problems on this exam. Work through the ones with which you are comfortable first. Do
notgetoverlycaptivatedbyinterestingdesignissuesorcomplexcornercasesyou’renotsureabout.
Notallinformationprovidedinaproblemmaybeuseful.
Unless otherwise stated, all given code on this exam should compile. All code has been compiled and
executed before printing, but in the unlikely event that we do happen to catch any bugs during the exam,
we’ll announce a fix. Unless we specifically give you the option, the correct answer is not ‘does not
compile.’
Theexamroughlyincreasesindifficultasyouapproachtheend.
Problem
0
1
2
3
4
5
6
7
8
9
10
11
12
13
Points
0.5
8
8
6
12
7.5
4
5
0
10
6
10
13
10
Optional.Markalongthelinetoshowyourfeelings Beforeexam: [:(____________________].
onthespectrumbetween:(and. Afterexam: [:(____________________].
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13

Partial preview of the text

Download CS61B: Data Structures Final Exam, Spring 2016 and more Exams Data Structures and Algorithms in PDF only on Docsity!

UC Berkeley – Computer Science CS 61 B: Data Structures Final, Spring 2016 This test has 13 questions worth a total of 100 points. The exam is closed book, except that you are allowed to use three pages (both front and back, for 6 total sides) as a written cheat sheet. No calculators or other electronic devices are permitted. Give your answers and show your work in the space provided. Write the statement out below in the blank provided and sign. You may do this before the exam begins. Any plagiarism, no matter how minor, will result in an F. **“I have neither given nor received any assistance in the taking of this exam.”



Signature: _______________________________ Name: ________________________ Your 3 Letter Login: _________ SID: ________________________ Name of person to left: _____________ No ID: ______ Exam Room: _________________ Name of person to right: _____________ No ID: ______ Primary TA: _________________** Tips: ● There may be partial credit for incomplete answers. Write as much of the solution as you can, but bear in mind that we may deduct points if your answers are much more complicated than necessary. ● There are a lot of problems on this exam. Work through the ones with which you are comfortable first. Do not get overly captivated by interesting design issues or complex corner cases you’re not sure about. ● Not all information provided in a problem may be useful. ● Unless otherwise stated, all given code on this exam should compile. All code has been compiled and executed before printing, but in the unlikely event that we do happen to catch any bugs during the exam, we’ll announce a fix. Unless we specifically give you the option, the correct answer is not ‘does not compile.’ ● The exam roughly increases in difficult as you approach the end. Problem 0 1 2 3 4 5 6 7 8 9 10 11 12 13 Points 0. 5 8 8 6 12 7. 5 4 5 0 10 6 10 13 10 Optional. Mark along the line to show your feelings Before exam: [:( ____________________☺]. on the spectrum between :( and ☺. After exam: [:( ____________________☺].

Login: _________ 0. So It Begins III ( 0. 5 points). Write your name and ID on the front page. Circle the exam room. Write the names of your neighbors. If a neighbor is missing their ID, make sure to mark No ID in the appropriate blank. Write and sign the given statement. Write your login in the corner of every page.

  1. Giraphage ( 8 points). For your convenience, we have provided 3 copies of the graph for parts a through c. a. ( 2 pts) For the graph above, give the vertices in the order they’d be visited by depth first search starting from vertex A, assuming that we always visit alphabetically earlier vertices first if there are multiple valid choices. You may not need all blanks. The alphabet is ABCDEFG. A ___B____ ___D____ ___E____ ___G____ ___C____ ___F____ _______ b. ( 2 pts) For the graph above, give the vertices in the order they’d be visited by breadth first search starting from vertex D, assuming that we always visit alphabetically earlier vertices first if there are multiple valid choices. You may not need all blanks. D ___A____ ___E____ ___B____ ___C____ ___G____ ___F____ _______ c. ( 2 pts) For the graph above, give the vertices in the order they’d be visited by Dijkstra’s algorithm starting from vertex A, assuming that we always visit alphabetically earlier vertices first if there are multiple valid choices. Assume that “visiting a vertex v” means “relaxing all of the edges out of v”. You may not need all blanks. A ___C____ ___B____ ___D____ ___E____ ___G____ ___F____ _______ Dijkstra’s works by expanding the node that is the least distance away from A first. d. Suppose we are trying to find the shortest path from A to G. Give an example of a heuristic function for which A* returns the wrong shortest paths tree. Specify your heuristic function by circling one number for h(E). h(A) = 0 h(B) = 3 h(C) = 2 h(D) = 2 h(E) = 4 1 2 5 8 14 h(F) = 1 h(G) = 0

Login: _________ c) ( 1 pt) Θ(N * log(N)) What is the worst case runtime of the sort described in part b? Give your answer in Big Theta notation in terms of N. Put your answer in the given blank.

Login: _________ 3. Reverse Engineering ( 6 Points). a. ( 4 pts) Consider the following unsorted array, and the array after an unknown number of iterations of selection sort as discussed in class (where we sort by identifying the minimum item and moving it to the front by swapping). Assume no two elements are equal. Unsorted: After? Iterations of Selection Sort: For each relation, circle <, >, or? if there is insufficient information to determine the relation between the two objects. For example, if you believe that is greater than , you’d circle the > on the first line. b. ( 2 pts) Suppose we have a graph G. All of G’s topological sorts are listed below. In the space to the right, fill in the adjacency list for G. There may be more than one right answer. Don’t worry about the exact formatting for your answer. As long as it is an adjacency list and it is easy to understand, we will accept your answer. Graph drawings will be given only partial credit please fill out the adjacency list! There are multiple answers. The minimal one is given. Note, topological sorts only exist for directed graphs! 1 2 3 4 5 6 7 1 2 3 4 6 5 7 1 3 2 4 5 6 7 1 3 2 4 6 5 7

Login: _________ 5. ( 7. 5 pts) Graph Algorithms. For each statement below, circle either TRUE or FALSE. If your answer is FALSE, draw a counterexample graph in the given box, and if applicable, provide a starting vertex. Please use unique edge weights for any weighted graphs. If your answer is true, don’t do anything in the box/blank. Any counterexamples should have 5 vertices or less. Keep in mind these are only worth 1. 5 points each! FALSE: The last edge added to the MST by Prim’s algorithm is always the highest weight edge in the MST. Starting vertex: A FALSE: The largest edge in a graph is never part of a SPT. Starting vertex: Either FALSE: On a graph of 4 or more nodes, DFS and BFS never visit vertices in the same order when run from the same start vertex. Starting vertex: A or D FALSE: Dijkstra’s algorithm always finds the shortest path in a directed acyclic graph, even if there are negative edges: Starting vertex: ____A____

Login: _________ FALSE: In any undirected graph, the shortests paths tree from any vertex always has total weight less than or equal to the weight of the MST for that graph. Starting vertex: ____A____

  1. Advanced Hash Party ( 4 points). ( 4 pts) There are other ways to resize a hash table than the way we discussed in lecture. For each scheme below, give the amortized best and worst case runtime for a single insertion operation in Θ notation in terms of N, the number of items in the hash table. If the operation given could result in an infinite runtime, write “infinity” or ∞ inside the big Theta. Assume the hashCode function takes constant time. By the “best case”, we mean a set of items that are spread out nicely by their hashCode, and by the “worst case”, we mean a set of items that have the worst possible collisions by their hashCode. Define L to be the average number of items in each bucket. Assume resizing takes linear time. Note: For all answers below, L is bounded above by a constant, so we do not include them as part of our answers. Best Case Worst Case Scheme Θ( 1 ) Θ( N ) Quadruple # of buckets when L > 1. Θ( 1 ) Θ( N ) Double # of buckets when L > 1 / 100. Θ( N ) Θ( N ) Increases # of buckets by 10 when L > 1 Θ( 1 ) Θ( ∞ ) Doubles # of buckets until no bucket has more than 5 elements in it. This may result in multiple doublings! Enjoy this space.

Login: _________ No, asymptotic runtime only applies for arbitrarily large inputs. If the input size is small, it is possible for g to execute faster than f (constant factors may become significant). 8. ( 0 points) Lloyd’s of London predicted in 2013 that this 1859 event, if it occurred today, would cause as much as 2. 6 trillion dollars of damage to the U.S. economy. What event were they referring to? Carrington event (solar storm)

Login: _________ 9. Heaps and JUnit ( 10 points). Write a JUnit test to check a method public void minheapify(int[] arr) {...} that is supposed to perform bottom up min heap heapification. This means ensuring that the array is actually a heap, and also that the array still has all the same items. Our tests will verify only correctness, not runtime. Assume there will be no duplicates (which may make it easier to test that the array still contains the same inputs after heapification). ● Hint: We’re not leaving index 0 blank, so the left child of k is 2 k + 1 , and the right child is 2 k + 2. ● Hint 2 : Feel free to use assertEquals(x, y), assertTrue(b), assertArrayEquals(x, y), etc. ● Hint 3 : If you don’t remember the exact syntax but your meaning is clear, penalties will be minimal. @Test public static void testHeapify() { int[] arr = generateRandomIntArray(); int[] original = new int[arr.length]; // copy of array before being heapified System.arraycopy(arr, 0 , original, 0 , arr.length); minheapify(arr); // Check the integrity of the result using one or two calls to helper methods testIsAHeap(arr); testHaveSameItems(original, arr); } private static void testIsAHeap(int[] arr) { for (int i = 0 ; i < arr.length; i++) { if ( 2 * i + 1 < arr.length) { assertTrue(arr[i] < arr[ 2 * i + 1 ]); } if ( 2 * i + 2 < arr.length) { assertTrue(arr[i] < arr[ 2 * i + 2 ]); } } } //You may not need all lines for these methods. Must include at least one assert! private static void testHaveSameItems(int[] original, int[] arr) { assertEquals(original.length, arr.length); for (int i = 0 ; i < arr.length; i++) { boolean exists = false; for (int j = 0 ; j < original.length; j++) { if (arr[i] == original[j]) { exists = true; } }

Login: _________ 10. Fancy Asymptotics ( 6 points) Ben Bitdiddle has created a generalized sorting algorithm called BitdiddleSort. The pseudocode is provided: procedure BitdiddleSort(array): if the array has length 1 : return the array else: divide the array into two equal halves, half 1 and half 2 sort half 1 using algorithm A sort half 2 using algorithm B merge the two sorted halves in O(N) time and return the merged result Let N be the length of the input array. Assume the array consists only of integers between 1 and 9. a) Suppose algorithm A is a comparison sort and algorithm B is counting sort. In big omega notation, give the tightest possible lower bound on the runtime of BitdiddleSort as a function of N. Hint (that you might not actually need): log(ab) = log(a) + log(b). Answer: Ω(N log N) was the intended answer because comparison sorting takes Ω(N log N) time in the worst case. But since the question didn’t specify “in the worst case”, Ω(N) is also acceptable. (For example, if the input is already sorted, then insertion sort, which is a comparison sort, runs in linear time.) b) Suppose algorithm A is counting sort and algorithm B is quicksort. In big O notation, give the tightest possible upper bound on the runtime of BitdiddleSort as a function of N. Answer: O(N^ 2 ). Quicksort runs in O(N^ 2 ) time and counting sort runs in O(N) time. c) Suppose algorithm A is quicksort and algorithm B is BitdiddleSort. In big O notation, give the tightest possible upper bound on the runtime of BitdiddleSort as a function of N. Answer: O(N^ 2 ). Quicksort runs in O(N^ 2 ) time. It’s applied to N/ 2 items, then N/ 4 items, then N/ 8 items, and so on. So the runtime is O(N^ 2 * ( 1 / 4 + 1 / 16 + 1 / 64 + … + 1 /N^ 2 )) = O(N^ 2 ). d) Suppose algorithm A and B are both BitdiddleSort. In big theta notation, give the runtime of BitdiddleSort as a function of N. Answer: ϴ(N log N). This is just mergesort.

Login: _________ 11. Dynamic Programming ( 10 points): Warning, the exam from here on out is pretty hard! Letters in the alphabet that are next to each other are said to be neighborly. For example, 'c' and 'd' are neighborly, and so are 'b' and 'a'. Note that 'a' and 'z' are not neighborly. Characters are also not neighborly with respect to themselves: 'a' and 'a' are not neighborly. Given a non empty array of lowercase characters ('a' through 'z'), find the length of the longest alphabetically neighborly subsequence (LANS) of the array. Remember that subsequences are not necessarily contiguous , and that neighborly can be either increasing or decreasing. Examples (read carefully!) :

  • For input ['a', 'b', 'c'], the answer is 3 , since the entire array is the LANS.
  • For input ['a', 'a', 'c', 'a', 'd'], the answer is 2 , since the LANS is the subsequence ['c', 'd'].
  • For input ['a', 'd', 'c', 'd'], the answer is 3 , since the LANS is the subsequence ['d', 'c', 'd'].
  • For input ['a', 'z', 'a', 'z'], the answer is 1 , since the LANS can be any character as a standalone subsequence, e.g. ['a']. Your algorithm must run in O(N) expected time, where N is the length of the input. Solutions that do not run in O(N) expected time will receive zero points. It is OK to assume constant time HashMap operations. You may assume you have access to the following 3 methods , which take constant, linear, and constant time: /* returns hm.get(key) if hm.containsKey(key), defaultValue otherwise / ● public static <K, V> V get(HashMap<K, V> hm, K key, V defaultValue) / returns the largest value in the HashMap hm (linear time) */ ● public static <K, V> V maxValue(HashMap<K, V> hm) ● Also, don’t forget about Math.max(int x, int y) and Math.min(int x, int y) Hint: You can use the subtraction operator to find the distance between two char values without casting to int. For example: 'b' 'a' evaluates to 1. Similarly: 'c' 1 evaluates to 'b'. public static int llans(char[] input) { HashMap<Character, Integer> cache = new HashMap<Character, Integer>(); cache.put(input[ 0 ], 1 ); for (int i = 1 ; i < input.length; i += 1 ) { int prev = get(cache, input[i] 1 , 0 ); int next = get(cache, input[i] + 1 , 0 ); cache.put(input[i], Math.max(prev, next) + 1 ); } return maxValue(cache); }

Login: _________ c. ( 5 points) Fill in the private collect method so that it behaves as in part b. Note that if topDigits is 0 you should not prepend a zero (in fact, it’s impossible), i.e. collect(z 10 , matches, 0 ) would add [ 0 , 110 ]. Assume that collect is never called on the root, so you don’t need to worry about any weird edge cases. Note that this method is a method of TrieIntegerSet , not Node. /* Collects a list of all keys in the subtrie rooted at x, assuming that

  • they are all prefixed by topDigits. Assume never called on root. / private void collect(Node x, List matches, int topDigits) { if (x == null) { return; } if (x.exists == true) { matches.add(topDigits * 10 + x.dig); } for (Node child : x.children) { collect(child, matches, topDigits * 10 + x.dig); __________________________________________________________________; } } // You may not need all lines. This is a time consuming problem. d. ( 5 points) Fill in the private method below such that public findRepeaters returns a list of all numbers in a TrieIntegerSet that have any consecutive repeated digits. For example, for the Trie from part a, this method would return [ 100 , 10110 , 1123 , 1134 , 355 ]. It would not return 2101 since the 1 s are not consecutive. You may use collect from part c even if you didn’t finish it or your answer is incorrect. You do not need to use the modulus operator % for this problem. Order doesn’t matter. This method also belongs to TrieIntegerSet. public List findRepeaters() { List matches = new ArrayList(); findRepeaters(root, matches, 0 ); return matches; } /* Finds all keys in the subtrie rooted in x that have at least one
  • pair of repeated digits, assuming they are all prefixed by topDigits. */ private void findRepeaters(Node x, List matches, int topDigits) { if (x == null) { return; } for (Node child : x.children) { if (x.dig == child.dig) { collect(child, matches, topDigits * 10 + x.dig); } else { findRepeaters(child, matches, topDigits * 10 + x.dig); }


} } // You may not need all lines. This is a time consuming problem.

Login: _________

  1. A (Fond?) Farewell to 61 B ( 10 points). In your life after 61 B, you'll often need to use one data structure to implement another. In this problem, you’ll build a FIFO (first in first out) queue of type MagicStringQueue which has two operations that are just like a regular queue, namely enqueue and dequeue. For example, if we made the following calls into an initially empty MagicStringQueue called mq: ● mq.enqueue(“giraffe”), mq.enqueue(“zebra”), mq.enqueue(“alf”) ● System.out.println(mq.dequeue()) Then the print statement would print “giraffe” since it was at the front of the queue. Instead of using an array or linked list to build the queue, you must use a MagicBag, which has the following operations: public void add(K key): adds an item of type K to the MagicBag, or replaces it if there is already an item that .equals key public K remove(K key): removes the item that .equals key (if it exists) and returns that item in the bag, or null otherwise Describe how you’d build a MagicStringQueue using only a MagicBag and a constant amount of additional memory. Solutions that use more memory will be given zero points.} Notes: You may assume that enqueue() is called at most 1 million times. Your MagicStringQueue may only use a constant amount of memory, except for a single MagicBag which may use linear memory. It is OK to create a single helper class (see part b of this problem). Strings are immutable in Java. a) List the instance variables of your MagicStringQueue. class MagicStringQueue { MagicBag bag; int addNumber, removeNumber; } b) Very briefly describe your helper class (if needed). List its instance variables as well as any methods. Briefly describe how any such methods work. Include any default methods that you @Override. class Helper { String value; int position; public Helper(String value, int position); public boolean equals(Object obj); // Dependent on position public int hashCode(); // Consistent with .equals } c) Describe how your MagicStringQueue’s enqueue and dequeue operations work in terms of its instance variables (including any calls to MagicBag’s methods). You may use pseudocode if you’d like. Do not write Java code. Don’t worry about handling dequeueing from an empty queue.

Login: _________ even a bit further, ALL data structures we’ve discussed in the course use constant time and memory since the memory of real computers is finite. Solution D: Magic bag has two String instance variables: first and last. Class Helper has two String instance variables, item and previous , and overrides the .equals method to only compare item. To enqueue, create a new Helper with item set to the new String and previous set to last , and then set last equal to the new String (also set first equal to the new String, if the MSQ is empty). To dequeue, set a variable temp equal to first , set first equal to MagicBag.remove(new Helper(item = first, previous = “”)).previous, and return temp. This solution was unexpected and a very clever way of essentially creating a linked list, but without actually using a linked list or nodes. Unlike solution B, the MagicBag is essential to the functioning of this implementation, rather than an afterthought to satisfy the problem statement. Unfortunately, It did not receive full credit because it does not handle duplicate Strings in the queue correctly (e.g., if “giraffe” is put in the queue multiple times at different locations).