Final Exam

Final Exam



Important notes:
  1. Do not start until you are instructed to do so!
  2. You will have 170 minutes once the proctor says to start.
  3. You will have brief additional time after we stop to scan and submit your solutions.

  4. Just before the exam...
    1. Have a fully-charged smartphone and laptop, and still plug both in if possible
    2. Log into Gradescope on your phone
    3. Change the screen timeout setting on your phone to never, so your screen doesn't go black if you don't interact with your screen for a while.
      • iPhones: Settings / Display & Brightness / Auto-Lock / Never
      • Android: Settings / Display / Screen timeout / 10 minutes (or the maximum amount of time)
    4. Turn on Do Not Disturb (or otherwise turn off all notifications).
    5. Position your webcam so we can see:
      • Your desk
      • The paper you are working on
      • Your writing utensil(s)
      • Both of your hands
      • Your phone

  5. During the exam:
    1. You may not ask questions during the exam.
      • If you are unsure how to interpret a problem, take your best guess.
      • If you feel a question is unfair because you could not ask a question about it, please email the instructor after the exam and describe your concern. (We are working hard to make the questions extra clear this year, but we want to know when we fail.)
    2. You may not touch your laptop or webcam.
      • This includes muting yourself at any point; the proctors may mute you though.
    3. All of these must be visible at all times:
      • Your desk
      • The paper you are working on
      • Your writing utensil(s)
      • Both of your hands
      • Your phone, with the exam webpage
    4. For any major tech fails (laptop or internet stops working, etc.):
      1. Stop taking the exam
      2. Email the instructor (rileyrd@cmu.edu) right away explaining the issue.
      3. Scan your progress so far to a PDF.
      4. Email that PDF to the instructor.
      5. We will reply soon to set up a 1-on-1 oral exam with the course faculty.

  6. After the exam:
    1. Follow all proctor instructions on how to end the exam.
    2. If you finish early, wait patiently until the end of the exam. (Note: Don't use your phone...)
    3. Keep everything in view (as noted above) until the proctor calls "time".
    4. When instructed, use your phone to scan your exam and submit the PDF to Gradescope.
    5. After submitting to Gradescope, hold your phone up to the webcam to show the receipt.
    6. Even then, remain in exam mode until the proctor calls "all clear"

1. Short Answer

Answer each of the following in just a few words.

Part A [2 pts]

What is the difference between a complete binary tree and a perfect binary tree?

Part B [2 pts]

The worst-case efficiency of inserting into a hash table is technically O(N), but in practice they are usually O(1). Why?

Part C [2 pts]

What is the largest, signed value that can be stored in a 6-byte integer? You do not need to reduce your answer. Be certain to show your work, and also very clearly circle your answer!

Part D [2 pts]

If you implement a queue with an ArrayList, can all the operations be O(1)? Why or why not?

Part E [2 pts]

Why should testcases be able to run and checking passing/failure automatically? (As opposed to requiring the developer to manually inspect the output.)

Part F [1 pts]

What does it mean when you get a NullPointerException?


2. Big-Oh

Determine the big-oh runtime of each of the following, in terms of N as specified in each problem. Circle your final answer for each.

Part A [3 pts]

// a contains N items
public static ArrayList<Integer> bigO1(HashSet<Integer> a) {
    ArrayList<Integer> b = new ArrayList<Integer>();
    for (int i : a) {
        i = Math.abs(i);
        if (i < 100) {
            b.add(i);
        }
    }
    return b;
}

Part B [3 pts]

// a contains N items, b contains N items
public static void bigO2(ArrayList<Integer> a, TreeSet<Integer> b) {
    for (int i : a) {
        if (!b.contains(i)) {
            b.add(i);
        }
    }
}

Part C [3 pts]

Be careful…

// a contains N items, b contains N items
public static void bigO3(HashSet<Integer> a, TreeSet<Integer> b) {
    ArrayList<Integer> c = bigO1(a);
    bigO2(c, b);
}

3. Linked List Memory Diagram [8 pts]

Consider the following code snippet that creates a linked list. You may assume that the ListNode class exists and was defined as in class.

ListNode<Integer> head = null;
ListNode<Integer> tmp = null;
ListNode<Integer> tmp2 = null;
ListNode<Integer> other = null;

head = new ListNode<Integer>(10);
printList(head);
// Stop and draw Diagram A.

tmp = new ListNode<Integer>(20);
tmp2 = new ListNode<Integer>(30);
other = new ListNode<Integer>(40);

tmp2 = head;
while(tmp2.next != null) {
    tmp2 = tmp2.next;
}
tmp2.next = tmp;
// Stop and draw Diagram B.

other.next = tmp;
// Stop and draw Diagram C.

head.next = other;
// Stop and draw Diagram D.

other.next.next = head;
head.next = null;
head = other;
// Stop and draw Diagram E.

Draw the state of the linked list, at each of the commented lines of code. The linked list is defined as starting at head. You do not need to draw the other three references (tmp, tmp2, or other).

The first one is drawn for you:

Draw the remaining four diagrams: Diagram B, Diagram C, Diagram D, and Diagram E.

Be sure to label each picture clearly with which Diagram it is.


4. BST Building

Imagine you are constructing a binary search tree of integers, and the following integers are added in the following order:

80, 13, 73, 59, 88, 60, 67, 94, 81, 6

Part A [4 pts]

Draw the resulting binary search tree.

Part B [4 pts]

Assuming you are using the in-order successor removal technique discussed in class, draw the state of your tree from Part A after 13 has been removed from it.


5. BST Traversal

Consider the following binary search tree:

Part A [3 pts]

Assuming the tree is traversed pre-order and the nodes printed, what is the resulting sequence? (Within the traversal, assume that left is followed before right.)

Part B [3 pts]

Assuming the tree is traversed post-order and the nodes printed, what is the resulting sequence? (Within the traversal, assume that left is followed before right.)

Part C [3 pts]

Assuming the tree is traversed in-order and the nodes printed, what is the resulting sequence? (Within the traversal, assume that left is followed before right.)


6. Heaps

Consider the following array representation of a binary heap:

     80 77 61 72 76 39 55 35 51 47                         

Part A [3 pts]

Draw the heap represented by this array.

Part B [2 pts]

Draw the heap after adding 70 to it. Show your work, but clearly mark your final answer. (Do not write your answer as an array, instead draw the final state of the heap.)

Part C [2 pts]

Building on your answer from part b, draw the heap after calling removeMax() on it. Show your work, but clearly mark your final answer. (Do not write your answer as an array, instead draw the final state of the heap.)


7. Free Response: The Quiz Policy [8 pts]

Consider the following excerpt from a course syllabus:

In order to reward improvement, I will replace one quiz score that is immediately followed by two higher scores. So, if you have a quiz that goes very badly, but your next two quizzes are each better than that bad quiz, I will replace that low quiz with the higher of the two scores immediately following it. If you have multiple "bad" quizzes that meet the criteria, I will replace the one that maximizes your point gain.

Write the static function lowestBeforeTwoIncreases which takes as an argument an array of integers (representing quiz scores), finds the quiz that needs to be replaced according the policy, and returns the difference between that quiz and the larger of the two quizzes that follow it. If there is no quiz that will be replaced, simply return 0.

For example, the following two examples each print 30:

int[] a = { 40, 20, 40, 35, 50, 65 };
System.out.println(lowestBeforeTwoIncreases(a));

int[] b = { 25, 30, 20, 45, 40, 60, 70, 80, 90, 100 };
System.out.println(lowestBeforeTwoIncreases(b));

The first example prints 30 because the quiz to be replaced is the 35, and it will be replaced by a 65, and the difference between those two is 30.

The second example prints 30 because the quiz to be replaced is the 40, and it will be replaced by a 70, and the difference between those two is 30.

Hint: You don’t actually need to figure out which element of the array will ultimately be replaced. Instead, you just need to figure out the largest difference among all candidates that meet the “lower before two higher” criteria.


8. Most Frequent Word [10 pts]

Consider the WordCounter class. It is used to catalog the occurrences of words and keep track of which word it has seen most often. It has the following methods:

Consider the following testcase:

WordCounter w = new WordCounter();
w.addWord("bun");
w.addWord("cat");
w.addWord("dog");
w.addWord("bun");
w.addWord("dog");
w.addWord("dog");

// This next line will print "dog", because "dog"
// has occurred 3 times in total.
System.out.println(w.mostFrequentWord());

w.loadFile("words.txt");

// This next line will print "bun", because "bun"
// has occurred 4 times in total.
System.out.println(w.mostFrequentWord());

words.txt contains:

bun
monkey
monkey
bun
monkey

Write the WordCounter class.

Note:


9. BST Free Response [10 pts]

Consider the following definition of a TreeNode:

public class TreeNode<DataType extends Comparable<DataType>> {
    public DataType data;
    public TreeNode<DataType> left;
    public TreeNode<DataType> right;

    public TreeNode(DataType data) {
        this.data = data;
    }
}

Notice this is a generic binary tree node, and could be used to build any sort of binary tree. (For example, this node could be used to build a binary search tree or a heap.)

Write the public static method isValidBST which takes as an argument a TreeNode representing the root of a tree, and returns true if that tree is a valid binary search tree and false otherwise.

Hints:


10. Welcome to the Jungle [20 pts]

In this problem you are going to write an Animal class. Here are some important requirements for your class:

Write the Animal class to the above specifications. Pay careful attention to which classes you may need to extend or implement as well as which methods you need to write or override.