CSCI 261 Fall 2021 -- Exam #2 Solutions Problem 1 --------- The mystery method takes a Stack of Integers as input, and removes all of the values <= 0. A good name might be keepPositives or removeNegatives (though that name wouldn't be precise about zero). The sentence above would get you full credit. Here's some extra detail: It's a recursive method where the base case is an empty stack, but there's nothing to do in that case -- there are no integers to remove from an empty stack. If it's *not* an empty stack then we pop the top item, make a recursive call to remove values <= 0 from the rest of the stack, and push the popped value back onto the stack if it's >0. It's like rebuilding a list we traverse via recursion: If we push items back after each recursive call, we'll "rebuild" the stack -- but in this case only with the values we want to keep. Problem 2 --------- a) head.next.next = head.next.next.next; Or, if you prefer to use a temporary pointer: Node temp = head.next; // Point at the node holding 4-sided die temp.next = temp.next.next; // Make it's next field point to 2's node b) Here's the code again, with comments: Node temp = head.next.next; // Point to node holding 8-sided die temp.next.data = head.data; // Make final node's data point to 6-sided die temp.next = head; // Make 8-sided die's node loop back to first node Problem 3 --------- Below are three equivalent ways to write it. We can only have a collision if there's a right-moving asteroid to the *left* of a left-moving asteroid. In other words, there's a collision if neighboring values are positive and then negative. These three versions look for that condition in different ways. /** * This one uses a boolean to keep track of whether we're in the left-moving * group or the right-moving group. Once we're seeing right-moving asteroids, * watch for a stray boulder moving left. */ public static boolean noCollisions(Queue roids) { boolean lefties = true; while(!roids.isEmpty()) { int next = roids.remove(); if (lefties) { // Processing left-moving asteroids if (next > 0) { // Now we're into right-moving lefties = false; } } else { // Processing right-moving asteroids if (next < 0) { // Oops -- found a leftie return false; } } } return true; } /** * This is exactly the same logic, but with the if statements simplified a bit. */ public static boolean noCollisions2(Queue roids) { boolean lefties = true; while(!roids.isEmpty()) { int next = roids.remove(); if (lefties && next > 0) { lefties = false; // Transitioning to right-moving } if (!lefties && next < 0) { return false; // Found left-moving amongst right-moving } } return true; } /** * This one simply watches for neighboring items where the first one is * right-moving and the second one is left-moving. It has to "remember" the * previous value as it goes. */ public static boolean noCollisions3(Queue roids) { if (roids.isEmpty()) { return true; } int prev = roids.remove(); while(!roids.isEmpty()) { int current = roids.remove(); if (prev > 0 && current < 0) { return false; } prev = current; } return true; } Problem 4 --------- Here's the code again: public static List evens(List nums) { if (nums.size() == 0) { return new LinkedList(); } else { int firstItem = nums.get(0); nums.remove(0); List evensFromTail = evens(nums); if (firstItem % 2 == 0) { evensFromTail.add(0, firstItem); } return evensFromTail; } } a) The method is polymorphic -- it takes an input of type List, so it be passed a LinkedList, an ArrayList, or any other subclass of List. b) The only operations the method performs on the input list, nums, are .get(0) and .remove(0). The .get(0) will be constant time on an ArrayList, but remove(0) is O(n). The .get(0) and .remove(0) would both be constant time on a LinkedList, so that would be the better choice. c) The method returns a LinkedList. The list is created in the base case, and added to as we come out of the recursive calls. d) The only operation on the list being returned is .add(0). That's O(n) for an ArrayList, but constant time for a LinkedList, so it would be more efficient to use a LinkedList as is being done here.