0% found this document useful (0 votes)
61 views

Problem Set 1 Solutions

This document contains the instructions for Problem Set 1 of the CSE 2011Z Winter 2014 course at York University, taught by Professor James Elder. It includes 7 problems related to logic, asymptotic analysis, data structures, and algorithms. Solutions will be posted on February 20. The problems cover topics like proving logical statements, analyzing asymptotic running times, defining Big-O notation, analyzing the running time of an array list method, designing algorithms to merge two linked lists and find the depth of nodes in a binary tree.

Uploaded by

rakeshgupta
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
61 views

Problem Set 1 Solutions

This document contains the instructions for Problem Set 1 of the CSE 2011Z Winter 2014 course at York University, taught by Professor James Elder. It includes 7 problems related to logic, asymptotic analysis, data structures, and algorithms. Solutions will be posted on February 20. The problems cover topics like proving logical statements, analyzing asymptotic running times, defining Big-O notation, analyzing the running time of an array list method, designing algorithms to merge two linked lists and find the depth of nodes in a binary tree.

Uploaded by

rakeshgupta
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

York University

CSE 2011Z Winter 2014 – Problem Set 1


Instructor: James Elder

Solutions will be posted Thursday, Feb 20.

1. Prove whether each of the following is true or false. x and y are real variables.

1) ∀x ∃y x·y =5
2) ∃y ∀x x·y =5
3) ∀x ∃y x·y =0
4) ∃y ∀x x·y =0
5) ∃a ∀x ∃y [x = a or x · y = 5]

• Answer:
(a) ∀x ∃y x · y = 5 is false. Let x = 0. Then y must be 50 , which is impossible.
(b) ∃y ∀x x · y = 5 is false. Let y be an arbitrary real value and let x = y6 if y 6= 0 and x = 0 if
y = 0. Then x · y 6= 5.
(c) ∀x ∃y x · y = 0 is true. Let x be an arbitrary real value and let y = 0. Then x · y = 0.
(d) ∃y ∀x x · y = 0 is true. Let y = 0 and let x be an arbitrary real value. Then x · y = 0.
(e) ∃a ∀x ∃y [x = a or x · y = 5] is true. Let a = 0. Let x be an arbitrary real value. If x = 0 then
[x = 0 or x · y = 5] is true because of the left. If x 6= 0 then let y = x5 and [x = 0 or x · y = 5]
is true because of the right.

2. Asymptotic Running Times


True or False? All logarithms are base 2. No justification is necessary.

(a) 5n2 log n ∈ O(n2 )


• Answer: False. It is a factor of log n too big.
(b) 48n ∈ O(84n )
• Answer: False: 48n = 216n , but 84n = 212n .
(c) 210 log n + 100(log n)11 ∈ O(n10 )
• Answer: True: 210 log n = n10 , 100(log n)11 ∈ O(n10 ).
(d) 2n2 log n + 3n2 ∈ Θ(n3 )
• Answer: False: 2n2 log n + 3n2 ∈ O(n3 ), but 2n2 log n + 3n2 ∈
/ Ω(n3 ).

1
3. Big-Oh Definition
Fill in the blanks:
f (n) ∈ O(g(n)) iff c > 0, n0 > 0, such that n n0 , f (n) cg(n)

• Answer:
f (n) ∈ O(g(n)) iff ∃ c > 0, ∃ n0 > 0, such that ∀ n ≥ n0 , f (n) ≤ cg(n)

4. Array Lists
What is the asymptotic running time of the method makeList below as a function of N ? Please justify
your answer.
1 public s t a t i c L i s t <I n t e g e r > makeList ( int N )
2 {
3 A r r a y L i s t <I n t e g e r > l i s t = new A r r a y L i s t <I n t e g e r >() ;
4
5 f o r ( int i = 0 ; i < N; i++ )
6 {
7 l i s t . add ( i ) ;
8 l i s t . trimToSize ( ) ;
9 }
10 }
11
12 /∗ ∗
13 ∗ Trims t h e c a p a c i t y o f t h i s A r r a y L i s t i n s t a n c e t o be t h e
14 ∗ l i s t ’ s c u r r e n t s i z e . An a p p l i c a t i o n can use t h i s o p e r a t i o n t o minimize
15 ∗ t h e s t o r a g e o f an A r r a y L i s t i n s t a n c e .
16 ∗/
17 public void t r i m T o S i z e ( ) {
18 modCount++;
19 int o l d C a p a c i t y = elementData . l e n g t h ;
20 i f ( s i z e < oldCapacity ) {
21 Object oldData [ ] = elementData ;
22 elementData = (E [ ] ) new Object [ s i z e ] ;
23 System . a r r a y c o p y ( oldData , 0 , elementData , 0 , s i z e ) ;
24 }
25 }

• Answer: makeList calls methods add and trimToSize once each on each iteration of the for
loop. On iteration i, both add and trimToSize
PN require that i array elements be copied to a new
array. Thus the asymptotic complexity is i=1 i = N (N + 1) /2.

5. Linked Lists
You are to design an efficient iterative algorithm listUnion(A, B) that accepts two singly-linked
lists, each containing a strictly increasing sequence of integers (i.e., with no repeating elements), and
merge them (take their union) into a single strictly increasing list of integers (again, with no repeating
elements). For example, the input A = [1, 4, 8, 10, 11, 20], B = [−5, 1, 8, 9, 20] should return a reference
to a list containing [−5, 1, 4, 8, 9, 10, 11, 20].
Your algorithm should use only O(1) additional memory beyond the two input lists, and should run in
O(max(m, n)) time, where m and n are the lengths of the two input lists.
Your algorithm is given only references A and B to the first nodes in each of the two input lists.
Each node is comprised only of val and next instance variables. You may assume that empty lists are

2
represented as null nodes and the next field of the last node in each list is set to null. No other list
variables are available to you.
Input: Two singly linked lists A and B, each containing a strictly increasing sequence of integers.
Output: The union of A and B as a singly linked list of strictly increasing integers.

(a) (20 marks) Your algorithm (in pseudocode or Java):


Algorithm listUnion(A,B):
• Answer:
1 package Midterm ;
2
3 public c l a s s L i s t U n i o n {
4 IntNode union ( IntNode A, IntNode B) {
5 IntNode C = null ;
6 IntNode c u r r = null ;
7 i f (A == null ) {
8 return (B) ;
9 } e l s e i f (B == null ) {
10 return (A) ;
11 } e l s e i f (A. v a l < B . v a l ) {
12 C = A;
13 A = A. next ;
14 } e l s e i f (B . v a l < A. v a l ) {
15 C = B;
16 B = B . next ;
17 } else {
18 C = A;
19 A = A. next ;
20 B = B . next ;
21 }
22 curr = C;
23 while (A != null && B != null ) {
24 i f (A. v a l < B . v a l ) {
25 c u r r . next = A;
26 A = A. next ;
27 } e l s e i f (B . v a l < A. v a l ) {
28 c u r r . next = B ;
29 B = B . next ;
30 } else {
31 c u r r . next = A;
32 A = A. next ;
33 B = B . next ;
34 }
35 c u r r = c u r r . next ;
36 }
37 i f (A != null ) {
38 c u r r . next = A;
39 } else {
40 c u r r . next = B ;
41 }
42 return C ;

3
43 }
44 }

(b) (5 marks) Your algorithm is efficient in both time and memory. What is the biggest sacrifice you
have made in achieving this efficiency?
• Answer: The algorithm destroys the input lists, which could lead to error if the caller is not
careful.

6. Choosing a data structure


State in one or two words the simplest ADT and implementation we have discussed that would meet
each requirement.
(a) O(1) time removal of the most recently added element
ADT: Implementation:
• Answer: Array-based stack
(b) O(1) average time addition, removal, access and modification of (key, value) pairs with unique
keys
ADT: Implementation:
• Answer: ADT: Map, Implementation: Hash table
(c) O(1) time insertion and removal at a given position
ADT: Implementation:
• Answer: ADT: Node List, Implementation: Linked List
(d) O(1) time index-based access and modification and amortized O(1) addition of elements
ADT: Implementation:
• Answer: ADT: Array List, Implementation: Extendable Array
(e) O(log n) time insertion of (key, value) entries and O(log n) removal of entry with smallest key
ADT: Implementation:
• Answer: ADT: Priority Queue, Implementation: Heap
(f) O(1) time removal of the least recently added element
ADT: Implementation:
• Answer: ADT: Queue, Implementation: (circular) array
7. Binary Trees
You are to design a recursive algorithm btDepths(u, d), where u is a node of a binary tree and d
is the depth of u. Your algorithm will determine the minimum and maximum depths of the external
nodes descending from u. Note that if u has no parent (i.e., is the root of the whole tree), then d = 0.
You can assume that each node v of the tree supports the following four binary tree accessor methods:
left(v), right(v), hasLeft(v) and hasRight(v). You can also assume that u is not null. Your
algorithm should run in O(n) time, where n is the number of nodes descending from u.
Input: A non-null node u of a binary tree, and its depth d.
Output: An object depths consisting of the two integer fields depths.min and depths.max, con-
taining the minimum and maximum depth over all external nodes descending from u.

(a) (20 marks) Your algorithm (in pseudocode or Java):


Algorithm btDepths(u, d):
• Answer:

4
if hasLeft(u) & hasRight(u)
leftDepths = btDepths(left(u),d+1)
rightDepths = btDepths(right(u),d+1)
depths.min = min(leftDepths.min,rightDepths.min))
depths.max = max(leftDepths.max,rightDepths.max))
return depths
elseif hasLeft(u) & !hasRight(u)
return btDepths(left(u),d+1)
else if !hasLeft(u) & hasRight(u)
return btDepths(right(u),d+1)
else // External node
depths.min = d
depths.max = d
return depths

(b) (5 marks) Provide a brief justification for why you think your algorithm is O(n).
• Answer: The algorithm visits each node exactly once, and does a constant amount of work
at each node. Thus the total work is O(n).

8. Largest Imbalance
Input: An n-node binary tree T .
Output: The largest imbalance in the tree, where the imbalance of a node x is the difference between
the lengths of the shortest and longest paths from x to a descendent external node. (Note: a leaf
is an internal node with no children, an external node is a ”nil” node child of an internal node.)
Design and analyze an efficient recursive algorithm for this problem.

• Answer:
algorithm Imbalance(tree)
< pre−cond >: tree is a binary tree.
< post−cond >: Returns the largest imbalance i as well as the lengths s and l of the shortest
and longest paths from the root node to an external node.
begin
if( tree = emptyT ree ) then
result( h0, 0, 0i )
else
hil , sl , ll i = Imbalance(tree.lef t)
hir , sr , lr i = Imbalance(tree.right)
s = min(sl , sr , ) + 1
l = max(ll , lr , ) + 1
i = max(il , ir , l − s)
result( hi, s, li )
end if
end algorithm
The time is O(n).

5
9. Order the following functions by increasing asymptotic growth rate:

4n log n + 2n 210 2log n


3n + 100 log n 4n 2n
n2 + 10n n3 n log n

• Answer:
(a) 210
(b) 2log n
(c) 3n + 100 log n
(d) 4n
(e) n log n
(f) 4n log n + 2n
(g) n2 + 10n
(h) n3
(i) 2n

10. Prove that n log n − n is Ω(n).

• Answer:
log n ≥ 2 ∀n ≥ 4. Thus n log n − n ≥ n ∀n ≥ 4 → n log n − n ∈ Ω(n).

11. Prove that if d(n) is O(f (n)) and e(n) is O(g(n)), then the product d(n)e(n) is O(f (n)g(n)).

• Answer:
d(n) ∈ O (f (n)) → ∃c1 , n1 > 0 : d(n) ≤ c1 f (n)∀n ≥ n1 .
Similarly,
e(n) ∈ O (g(n)) → ∃c2 , n2 > 0 : e(n) ≤ c2 f (n)∀n ≥ n2 .
Thus, letting c0 = c1 c2 and n0 = max {n1 , n2 }, we have
d(n)e(n) ≤ c0 f (n)g(n)∀n ≥ n0 → d(n)e(n) ∈ O (f (n)g(n)).

12. What are the asymptotic running times of the methods add and remove of the class SparseNumer-
icVector that you modified for Programming Question 1?

• Answer:
They are both Θ(n), where n is the number of non-zero elements in the vector.

13. An evil king has n bottles of wine, and a spy has just poisoned one of them. Unfortunately, they dont
know which one it is. The poison is very deadly; just one drop diluted even a billion to one will still kill.
Even so, it takes a full month for the poison to take effect. Design a scheme for determining exactly
which one of the wine bottles was poisoned in just one months time while expending only O (log n)
royal tasters. State your scheme briefly, in English.

• Answer: Label each bottle from 1 to n, and consider each as a binary number consisting of dlog ne
bits. Now assemble dlog ne royal goblets. Take a drop from each of the bottles whose lowest order
bit is set and deposit in the first goblet. Then take a drop from each bottle whose 2nd bit is
set and deposit in the second goblet. Continue in similar fashion through the highest-order bit.
Now hand each of the royal tasters one of the goblets and command them to drink. Note that
there is now a 1:1 correspondence between bits and tasters. In a month, some of your tasters will
drop dead. Set the corresponding bits to 1, and all other bits to 0. The resulting binary number
identifies the poisoned bottle. Long live the king!

6
14. Give an example of a Java code fragment that performs an array reference that is possibly out of
bounds, and if it is out of bounds, the program catches that exception and prints the following error
message: Dont try buffer overflow attacks in Java!

• Answer:
1 try {
2 v a l = myArray [ i d x ] ;
3 System . out . p r i n t l n ( ”The v a l u e s t o r e d a t p o s i t i o n ”+i d x+” o f myArray
i s ” + val ) ;
4 } catch ( ArrayIndexOutOfBoundsException a i o o b x ) {
5 System . out . p r i n t l n ( ”Don ’ t t r y b u f f e r o v e r f l o w a t t a c k s i n Java ! ” ) ;
6 }

15. Asymptotic Running Times


True or False? All logarithms are base 2. No justification is necessary.

(a) 2n ∈ Ω n3
• Answer: True

(b) 3n3 + 17n2 ∈ O n3
• Answer: True. For example, 3n3 + 17n2 ≤ 20n3 ∀n ≥ 1.
(c) 5n2 log n ∈ O(n2 )
• Answer: False. It is a factor of log n too big.
10 log n
(d) 2 + 100(log n)11 ∈ O(n10 )
• Answer: True: 210 log n = n10 , 100(log n)11 ∈ O(n10 ).
(e) 2n2 log n + 3n2 ∈ Θ(n3 )
• Answer: False: 2n2 log n + 3n2 ∈ O(n3 ), but 2n2 log n + 3n2 ∈
/ Ω(n3 ).
16. Show that n2 is Ω (n log n).

• Answer: We seek a c > 0, n0 > 0 : ∀n ≥ n0 , n2 ≥ cn log n ↔ n ≥ c log n. Let c = 1. Then we


require that n ≥ log n. This is satisfied ∀n ≥ 1. Thus n2 is Ω (n log n).

17. Suppose you have a stack S containing n elements and a queue Q that is initially empty. Describe (in
pseudocode or English) how you can use Q to scan S to see if it contains a certain element x, with the
additional constraint that your algorithm must return the elements back to S in their original order.
You may not use an array or linked list only S and Q and a constant number of reference variables.

• Answer: We use the queue Q to process the elements in two phases. In the first phase, we
iteratively pop each element from S and enqueue it in Q, and then we iteratively dequeue each
element from Q and push it into S. This reverses the elements in S. Then we repeat this same
process, but this time we also look for the element x. By passing the elements through Q and
back to S a second time, we reverse the reversal, thereby putting the elements back into S in their
original order.

18. Describe the structure and pseudo-code for an array-based implementation of the array list ADT that
achieves O(1) time for insertions and removals at index 0, as well as insertions and removals at the end
of the array list.

7
• Answer: A simple solution is to adapt the array-based queue implementation described in Section
5.2.2 of the text. This employs front and rear indices f and r, and modular arithmetic to use the
array in a circular way. We modify the operation slightly, so that f and r will always point to
the next available element at the beginning and end of the list, respectively. Thus f and r will
be initialized to locations 0 and 1 of the array respectively, and the array will be considered full
when f=r. Thus an array of size N will support an Array List of size N-1.
Instead of implementing the front(), enqueue(e) and dequeue() methods of the queue ADT, we
implement the get(i), set(i, e), add(i, e) and remove(i) methods of the Array List ADT in the
following way, based upon an array of size N:
– get(i): return the element from location (f+i+1) mod N
– set(i, e): set the element at location (f+i+1) mod N to e
– add(i, e):
∗ If i ¡ size()/2
· Shift all elements with indices less than i to the left one position (using modular arith-
metic).
· f ← (f − 1)modN
· set the element at location (f+i+1) mod N to e
∗ Otherwise
· Shift all elements with indices greater than or equal to i to the right one position (using
modular arithmetic).
· r ← (r + 1)modN
· set the element at location (f+i+1) mod N to e
– remove(i):
∗ If i ¡ size()/2
· Shift all elements with indices less than i to the right one position (using modular
arithmetic).
· f ← (f + 1)modN
∗ Otherwise
· Shift all elements with indices greater than i to the left one position (using modular
arithmetic).
· r ← (r − 1)modN
If an add(i,e) message is received for a full array, the array must be extended, as for the standard
Array List implementation.

19. Describe (in pseudocode or English) an algorithm for reversing a singly linked list L using only a
constant amount of additional space and not using any recursion.

• Answer: The solution requires 3 pointers, prev, curr and next. prev is required as the new target
for curr.next. next is required so that we do not lose our reference to the rest of the list when we
redirect curr.next.
if head = null then
return head
end if
prev← head
curr ← prev.next
if cure = null then
return head
end if

8
next ← curr.next
prev.next ← null
curr.next ← prev
while next 6= null do
prev ← curr
curr ← next
curr.next ← prev
next ← next.next
end while
head ← cure

20. Describe how to implement an iterator for a circularly linked list. Since hasNext() will always return
true in this case, describe how to perform hasNewNext(), which returns true if and only if the next
node in the list has not previously had its element returned by this iterator.

• Answer: The iterator simply maintains two instance variables called start and next, which are
both initialized to cursor. If start is encountered while incrementing next, the next variable is set
to null, signaling a complete cycle of the list.

Algorithm next()
if next = null then
throw exception
end if
curr ← next
if next.getNext() = start then
next ← null
else
next ← next.getNext()
end if
return curr

Algorithm hasNewNext()
if next 6= null then
return true
else
return false
end if

21. Describe (in pseudocode or English) an O(n) recursive algorithm for reversing a singly linked list L, so
that the ordering of the nodes becomes opposite of what it was before.

• Answer: We simply recurse to the end of the list and then reverse pointers as the recursion
unwinds, returning the last node on the way back, and making it the new head.
From an inductive point of view, at any intermediate node we have a ”friend” provide us with the
reversal of the tail section of the list to the right of our node, and then simply update the new
tail of that tail section to point to our node.

Algorithm reverse()

9
newHead ← reverseSub(head)
head.next ← null
head ← newHead

Algorithm reverseSub(node)
if node.next 6= null then
newHead ← reverseSub(node.next)
node.next.next ← node
return newHead
else
return node
end if
22. Describe (in pseudocode or English) an algorithm that will output all of the subsets of a set of n
elements (without repeating any subsets). What is the asymptotic running time of your algorithm?
• Answer: Here, our ”friend” returns to us the complete set of subsets SS of the input set minus
the first element. Then all we have to do is make sure we return the union of this set of subsets
SsS with the set of subsets formed by adding this first element to each of the sets in SsS.
We use the symbol to denote set complement (i.e., S S.first is the set S with the element S. first
removed) and to denote set union.
The work done in each stackframe is proportional to the number of sets in NSsS, which is 2i at a
recursion height of i. Thus running time is O(2n).
Notation:

– S = input Set of elements


– SsS = Set of subSets
– NSsS = New Set of subSets
– sS = one subSet

Algorithm subsets(S)
if S = null then
return null
end if
SsS ← subsets(S S.first)
NSsS ← SsS
for all sS in SsS do
Add Si S.first to NSsS
end for
return NSsS
23. The balance factor of an internal node v of a proper binary tree is the difference between the heights
of the right and left subtrees of v. Describe (in pseudocode or English) an efficient algorithm that
specializes the Euler tour traversal of Section 7.3.7 to print the balance factors of all the internal nodes
of a proper binary tree.
• Answer: One way to do this is to extend the binary tree node class to support a height instance
variable. Then the visitRight() method can be used to both update the height variables and to
print the balance factors:

10
Algorithm visitRight()
if v.isInternal(v) then
v.height ← max(v.leftchild.height, v.rightchild.height) + 1
balance ← absval(v.rightchild.height − v.leftchild.height)
else
v.height ← 0
balance ← 0
end if

24. Let T be a tree with n nodes. Define the lowest common ancestor (LCA) between two nodes v and
w as the lowest node in T that has both v and w as descendents (where, by definition, a node is
a descendent of itself). Given two nodes v and w, describe (in pseudocode or English) an efficient
algorithm for finding the LCA of v and w. What is the running time of your algorithm?

• Answer: We assume that each node is extended to include an instance variable depth containing
the depth of the node. Then our algorithm simply takes the deeper node and traces a path back
toward the root until the depths of the two nodes match. Then both nodes are backed up toward
the root in tandem until they meet. The algorithm is O(h), where h is the height of the tree.

Algorithm LCA(Node v, Node w)


while v.depth > w.depth do
v ← v.parent
end while
while w.depth > v.depth do
w ← w.parent
end while
while v 6= w do
v ← v.parent
w ← w.parent
end while
return v

25. We can represent a path from the root to a given node of a binary tree by means of a binary string,
where 0 means go to the left child and 1 means go to the right child. Use this to design an time
algorithm for finding the last node of a complete binary tree with n nodes, assuming a linked structure
implementation that does not keep a reference to the last node.

• Answer: The path to the last node in the heap is given by the path represented by the binary
expansion of n with the highest-order bit removed.

26. Given a heap T and a key k, give an algorithm to compute all of the entries in T with key less than or
equal to k. The algorithm should run in time proportional to the number of entries returned.

• Answer: Starting at the root of the tree, recursively search the left and right subtrees if the root
of the subtree has a key value less than or equal to k, returning each nod visited.

11

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy