CS 307, Fall 2005, Midterm 2 Suggested Solution and Grading Criteria Question 1. 2 points per part. Correct answer or -2. On Big O leaving off O( ) okay. Example, N instead of O(N), okay. Correct name of Big O functions also okay. Example: constant instead of O(1) 1. A. 18 B. 42*24 C. 37 D. manam E. O(N) F. O(1) G. 6N + 7, range on N: 5N - 7N okay. range on constant: 6 - 8 okay. H. O(N) I. O(N^3) J. O(N^2) K. O(logN) base 2 okay, but not required L. 32 seconds M. 20,000 seconds N. For a linked list a linear search will be more efficient than binary. This is because getting an element in the middle of the list takes O(N) time, so it is faster to just do a linear search. (Or words to that affect. Partial credit possible.) O. To achieve the worst case the value selected as the pivot must always be either the smallest or largest value in the list being sorted. (Or words to that effect. Partial credit possible.) 2. Suggested solution: public UnsortetSet(Bag b) { myCon = new Object[b.size]; mySize = 0; Iterator it = b.iterator(); Object temp; boolean present; int index = 0; while( it.hasNext() ) { temp = it.next(); present = false; index = 0; //check to see if temp present in my container while( !present && index < mySize) { present = myCon[index].equals(temp); index++; } // if not present, add to my container if( !present ) { myCon[mySize] = temp; mySize++; } } } Criteria: Create container and ensure large enough while adding (can be done at beginning) +1 attempt +1 correct set mySize +1 attempt +1 correct Check all items in Bag. (most likely via Iterator) +3 attempt +3 correct Check if current item already present in Set. Many ways to do this. +2 attempt +2 correct Add item if not already present +3 attempt +3 correct The Bag sent as a parameter is not to be destroyed. 3. Suggested Solution public LinkedList split() { LinkedList result = new LinkedList(); if( mySize > 1 ) { myTail = myHead; result.myHead = myHead.getNext(); result.myTail = result.myHead; ListNode temp = myHead.getNext().getNext(); for(int i = 3; i <= mySize; i++) { if( i % 2 == 1) { myTail.setNext(temp); myTail = temp; } else { result.myTail.setNext(temp); result.myTail = temp; } temp = temp.getNext(); } myTail.setNext(null); result.myTail.setNext(null); result.mySize = mySize / 2; mySize = mySize - result.mySize; } return result; } Note, there were many, many ways to do this. Only a handful of solutions were a like. One disturbing question I was asked many times during the test was how to access the result's private instance variables. Recall, in Java, you can access private instance variables for all objects which are the same type as the class a method belongs to. Split is in the LinkedList class so it has access to the calling object's private instance variables as well as every other LinkedList object that may be in scope. Criteria: Create resulting LinkedList +1 attempt +2 correct iterate through original list +4 attempt +4 correct decide which list to add a node to +3 attempt +3 correct link nodes +3 attempt +3 correct update sizes +1 attempt +1 correct 4. Suggested solution. public static int numCombos(int[] dice, int target){ return diceHelper(0, dice, target, 0); } public static int diceHelper(int current, int[] dice, int target, int total){ // considered all dice? correct total? if(current == dice.length && target == total) return 1; // considered all dice and incorrect total, or total not possible else if( current == dice.length || total + (dice.length - current) > target) return 0; // take one die and consider its sides else { int numWays = 0; for(int i = 1; i <= dice[current]; i++) numWays += diceHelper(current + 1, dice, target, total + i); return numWays; } } This is essentially the same algorithm as the phone number problem from the homework. Criteria: iterate through all sides of given die +3 attempt +3 correct choose all dice +5 attempt +6 correct accumulate sum of dice +2 attempt +2 correct accumulate number of combos equal to total +2 attempt +2 correct hard coded problem for 3 dice -18 too many or too few combos -10