Problem #1
Preorder traversal 8, 7, 2, 4, 9, 5, 1, 3, 6, 0
Inorder traversal 4, 2, 9, 7, 8, 3, 1, 6, 5, 0
Postorder traversal 4, 9, 2, 7, 3, 6, 1, 0, 5, 8
2 points each, only partial credit is if the sequence matches the right answer
other than one single error (missing number, wrong number, transposed pair)
-------------------------------------------------------------------------------
problem #2
+------------+
| George |
+------------+
/ \
/ \
/ \
+------------+ +------------+
| Emma | | Jane |
+------------+ +------------+
/ \ / \
/ \ / \
/ \ / \
+------------+ +------------+ +------------+ +------------+
| Elton | | Frank | | Harriet | | Weston |
+------------+ +------------+ +------------+ +------------+
Only partial credit is 2 out of 4 points if just one node is in the wrong
place.
-------------------------------------------------------------------------------
Problem #3
Method Call Contents of Set Returned
-----------------------------------------------
mystery(grid, 2, 2) [6, 7]
mystery(grid, 0, 2) [1, 2, 5, 8]
mystery(grid, 3, 3) [1, 2, 3, 7, 9]
1 pt for first problem
2 pt for second problem
2 pt for third problem
-1 for order error (just once)
-1 for duplicates (just once)
-1 for missing number
-1 for extra number
no subproblem can go negative
Problem #4
solutions
public Set removeDuplicates(List list) {
Set result = new HashSet();
Iterator itr = list.iterator();
while (itr.hasNext()) {
Point p = itr.next();
if (result.contains(p)) {
itr.remove();
} else {
result.add(p);
}
}
return result;
}
public Set removeDuplicates(List list) {
Set result = new HashSet();
for (int i = 0; i < list.size(); i++) {
if (result.contains(list.get(i))) {
list.remove(i);
i--;
}
result.add(list.get(i));
}
return result;
}
1 correct header (static is okay)
2 construct and return the set of values from the list
1 reasonable attempt (at least 3 of: constructing a set, HashSet, attempt
to add values from list, return)
1 all correct assuming code to remove duplicates from list is correct
(including Set interface for variable)
2 remove duplicates from the list
1 reasonable attempt
1 correct
Problem #5
solutions
public int oddPathSum() {
return oddPathSum(overallRoot, 0);
}
private int oddPathSum(IntTreeNode root, int sum) {
if (root == null) {
return 0;
} else {
sum += root.data;
int result =
oddPathSum(root.left, sum) + oddPathSum(root.right, sum);
if (sum % 2 != 0) {
result++;
}
return result;
}
}
---------------------------------------------------------------------------
public int oddPathSum() {
return oddPathSum(overallRoot, false);
}
private int oddPathSum(IntTreeNode root, boolean odd) {
if (root == null) {
return 0;
} else {
if (root.data % 2 != 0) {
odd = !odd;
}
int result =
oddPathSum(root.left, odd) + oddPathSum(root.right, odd);
if (odd) {
result++;
}
return result;
}
}
---------------------------------------------------------------------------
public int oddPathSum() {
return oddPathSum(overallRoot, 0, 0);
}
private int oddPathSum(IntTreeNode root, int sum, int count) {
if (root == null) {
return count;
} else {
sum += root.data;
count = oddPathSum(root.left, sum, count);
count = oddPathSum(root.right, sum, count);
if (sum % 2 != 0) {
count++;
}
return count;
}
}
---------------------------------------------------------------------------
public int oddPathSum() {
return oddPathSum(overallRoot, 0);
}
private int oddPathSum(IntTreeNode root, int n) {
if (root == null)
return 0;
n = (n + root.data) % 2;
return n + oddPathSum(root.left, n) + oddPathSum(root.right, n);
}
---------------------------------------------------------------------------
1 public header
1 overall setup: private method returning an int with a root parameter and a
second parameter that can keep track of odd path sum (e.g., sum/boolean),
public method calls private method passing it overallRoot and appropriate
starting value for second parameter, public method returns result of private
method
1 base case for null (tests for this and prevents any NullPointerException)
2 recursive calls
1 their answer includes recursive calls on root.left and root.right that
include some kind of path sum parameter
1 correctly traverses the entire tree
2 correctly computes a value that can be used for odd path sum (for these
points, don't worry about whether their tests for odd path sum are correct;
you want to look at the initial call with overallRoot, how they incorporate
root.data, and the recursive calls they are making to see if the pieces fit
together to produce a value that can be tested for odd/even path sum):
1 reasonable attempt
1 correct (requires a recursive call on both left and right, but assume the
tree is traversed correctly)
3 correctly counts odd path sums
1 reasonable attempt: testing for odd path sum and returning a different
value in that case
2 correct (-1 if minor error like obob or counting even path sums)
notes:
* a count field loses the overall setup point if private method has void return
and always loses the 2 counting correctness points
* give to question leader any solutions that change the tree or use extra data
structures (even a string)
Problem #6
solutions
public void recordGrade(Map> grades,
String id, double grade, String course) {
if (!grades.containsKey(id)) {
grades.put(id, new TreeMap());
}
Map next = grades.get(id);
if (next.containsKey(course)) {
grade = Math.max(grade, next.get(course));
}
next.put(course, grade);
}
public void recordGrade(Map> grades,
String id, double grade, String course) {
if (!grades.containsKey(id)) {
grades.put(id, new TreeMap());
}
Map map = grades.get(id);
if (!map.containsKey(course) || map.get(course) < grade) {
map.put(course, grade);
}
}
2 header (static is okay, non-void okay if there is a return that is
consistent, interfaces required, -1 if method name is wrong, -1 per
incorrect parameter)
3 adds student to overall map if not seen before
1 reasonable attempt to test whether ID is in the overall map
1 reasonable attempt to construct a student map (string->double) for each
student (can get this point even if they do it every time)
1 all correct (constructs a new TreeMap exactly once each time an ID is
seen for the first time and adds it to the overall map, constructed map
is a TreeMap, syntax is correct; very nitpicky, including "()" in call to
TreeMap constructor)
3 finds the max of new grade and any previously recorded grade
1 reasonable attempt to test whether grade is already in student map
1 reasonable attempt to find max of old grade and new grade
1 all correct (very nitpicky, including using "()" when necessary, but
don't take off for nitpicky syntax twice)
2 records the grade in the student map
1 reasonable attempt
1 all correct
notes:
can't get both "reasonable attempt to test in map" unless there are two maps
Problem #7
solution
public class AdmissionsEntry implements Comparable {
private String ID;
private int ratings;
private double total;
private boolean discuss;
public AdmissionsEntry(String ID) {
this.ID = ID;
this.ratings = 0;
this.total = 0.0;
this.discuss = false;
}
public void rate(double rating) {
ratings++;
total += rating;
if (rating >= 4) {
discuss = true;
}
}
public void flag() {
discuss = true;
}
public String getID() {
return ID;
}
public double getRating() {
if (ratings == 0) {
return 0.0;
} else {
return total / ratings;
}
}
public String toString() {
double rating = Math.round(100 * getRating()) / 100.0;
return ID + ": " + rating;
}
public int compareTo(AdmissionsEntry other) {
if (discuss && !other.discuss) {
return -1;
} else if (!discuss && other.discuss) {
return 1;
} else if (getRating() > other.getRating()) {
return -1;
} else if (getRating() < other.getRating()) {
return 1;
} else {
return ID.compareTo(other.ID);
}
}
}
1 class header
4 fields (1 point each, -1 once if not private, okay to have extra field(s)
get 1 of 2 points for list of ratings instead of count/total)
1 constructor (can rely on defaults for ratings, total, discuss; requires
constructing list of ratings if they are using that approach)
2 rate method
1 reasonable attempt to record this rating in a field
1 all correct (requires ratings and total field or list, has to record the
score in such a way that an average can be computed)
2 correctly flagging students to be discussed (requires flag field)
1 correct flag method OR correctly flags ratings > 4 in rate method OR
reasonable attempt at both
1 correct flag method AND correctly flags ratings > 4 in rate method
1 correct getID method
2 getRating method
1 reasonable attempt
1 all correct
2 toString
1 reasonable attempt (4 of the following 7: id, colon, average rating,
dealing with ratings = 0, * 100 / 100, round, return--getRating gets both
average rating and dealing with ratings=0)
1 correct (must work when ratings=0, must round to 2 digits, must guarantee
double division, must include colon but space is not required)
5 compareTo
1 reasonable attempt to put flagged students first
1 correctly puts flagged students first
1 reasonable attempt to reverse order by ratings when flag matches
1 reasonable attempt to order by ID when flag and ratings match
1 correctly reverses order by ratings when flag matches and correctly
orders by ID when flag and ratings match
notes:
give question leader odd solutions like array of ratings
Problem #8
solutions
public void tighten() {
overallRoot = tighten(overallRoot);
}
private IntTreeNode tighten(IntTreeNode root) {
if (root != null) {
root.left = tighten(root.left);
root.right = tighten(root.right);
if (root.left == null && root.right != null) {
root = root.right;
} else if (root.left != null && root.right == null) {
root = root.left;
}
}
return root;
}
private IntTreeNode tighten(IntTreeNode root) {
if (root != null) {
if (root.left == null && root.right != null)
root = tighten(root.right);
else if (root.left != null && root.right == null)
root = tighten(root.left);
else {
root.left = tighten(root.left);
root.right = tighten(root.right);
}
}
return root;
}
private IntTreeNode tighten(IntTreeNode root) {
if (root != null) {
if (root.left == null && root.right != null)
return tighten(root.right);
else if (root.left != null && root.right == null)
return tighten(root.left);
root.left = tighten(root.left);
root.right = tighten(root.right);
}
return root;
}
1 public header
1 overall setup: private header with a root parameter and public method calls
private method passing it overallRoot
5 used x = change(x) or equivalent (ok to give "equivalent" to question leader)
1 overallRoot = recurse(overallRoot)
1 private method has return type IntTreeNode
1 root.left = recurse(root.left) (at least one; all left are like this)
1 root.right = recurse(root.right) (at least one; all right are like this)
1 returns root or modified root in all cases
2 base case for root == null
1 attempt (tested this case)
1 correct: requires test, no NullPointerException, tree not changed in this
case
3 Eliminating 1-child nodes
1 reasonable attempt to replace root with non-null child (other child null)
1 correctly resets root or returns child for one of the two 1-child cases
1 correctly resets root or returns child for other 1-child case
2 2-child case works (recursive calls for both children)
2 leaf case works assuming null test works (unchanged)--requires tests
4 recursive calls are made for 1-child cases
1 exist
3 before assignment or in assignment/return
notes:
Give to question leader solutions that avoid x=change(x), that have extra
data structures, that change data fields, that are inefficient (might not be
O(n)) and anything else odd.
Problem #9
solutions
public LinkedIntList removeFirstOf3() {
LinkedIntList other = new LinkedIntList();
if (front != null) {
other.front = front;
ListNode back1 = other.front;
front = front.next;
ListNode current = front;
while (current != null && current.next != null &&
current.next.next != null) {
current = current.next;
back1.next = current.next;
back1 = back1.next;
current.next = current.next.next;
current = current.next;
}
back1.next = null;
}
return other;
}
---------------------------------------------------------------------------
public LinkedIntList removeFirstOf3() {
LinkedIntList other = new LinkedIntList();
front = recurse(front, other, 1);
return other;
}
private ListNode recurse(ListNode front, LinkedIntList other, int count) {
if (front != null) {
front.next = recurse(front.next, other, count + 1);
if (count % 3 == 1) {
ListNode temp = front.next;
front.next = other.front;
other.front = front;
return temp;
}
}
return front;
}
1 header (lose this if return type is ListNode even if they return a ListNode)
2 constructs and returns other LinkedIntList
1 reasonable attempt (can get this even if they are returning a ListNode)
1 correct (requires call on LinkedIntList constructor, proper return)
2 sets next link of final node moved to list2 to null
1 reasonable attempt to set the next field to null for some node being
moved
1 correctly sets the next field to null for the final node moved in every
case they get credit for below (requires that they get a case that
required setting to null--length 2, 3, 5, 6, 8, 9, 11, 22, etc)
4 basic cases that don't require a loop (assuming final node link set to null)
1 empty list
1 length 1
1 length 2
1 length 3
2 generous pattern match
1 using curr1/curr2 variables to keep track of a position in each of the
two lists (curr2 could be other.front)
1 one of the following:
* loop that moves curr1 forward three positions in list1 (consider the
effect of code that resets current and that removes nodes from list1)
* reasonable attempt to remove from list1, as in:
curr1.next = curr1.next.next;
(requires resetting a next field)
* reasonable attempt to move a node to list2, as in:
curr2.next = curr1;
curr2.next = curr1.next;
(requires resetting a next field)
9 other specific cases (assuming final node link set to null):
1 length 4
1 length 5
1 length 6
1 length 7
1 length 8
1 length 9
1 length 16
1 length 17
1 length 18
Notes:
-1 if they say other when they mean other.front (but only if that raises their
score)
We have a general rule that if you can fix one problem and it suddenly works,
then we make that fix and charge them 5 points. If this gives someone a higher
score, you can grade it that way. But don't spend too much time trying to
figure out their mistakes.
Any O(n^2) solutions or odd solutions (new nodes, changing data) go to the
question leader.
Stuart Reges
Last modified: Fri Sep 16 16:16:07 PDT 2011