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