You are on page 1of 11

Solution - Practice Final Examination 

420-ENM-MT 
 
Name: 
Student ID: 
Group:    
Problem 1 (20 points) 
 
Consider the following operations on a stack and a queue. 
 
stack = empty stack 
queue = empty queue 
 
for each n from 0 to 3: 
stack.push(n) 
 
stack.push(4) 
item1 = stack.pop() 
queue.enqueue(item1) 
 
# Before the while loop 
 
while stack is not empty: 
item2 = stack.pop() 
queue.enqueue(item2) 
 
# After the while loop 
 
 
a) ​(10 points) Draw what the ​stack l​ ooks like b
​ efore​ the while-loop. 
 
 
→ [3, 2, 1, 0] 
 
 
 
b) (​ 10 points) Draw what the q
​ ueue ​looks like a
​ fter​ the while-loop. 
 
 
→ [0, 1, 2, 3, 4] →   
Problem 2 
 
Write p​ seudocode ​for the following algorithms 
 
a) ​Write an algorithm called​ count_in_range w ​ hich takes a list of integers, an 
integer​ min ​ and an integer​ max a​s arguments and returns the count of 
number from the list which is between​ min a ​nd​ max​ .  
 
Example:  count_in_range([5, 2, 8, 7, 11], 2, 7) → 3 
 
function count_in_range(list, min, max): 
count = 0 
for each element in list: 
if min <= element <= max: 
increment count 
return count 
 
 
b)​ Write an algorithm called​ reverse ​which takes a queue as argument, 
reverses it and returns it. 
 
We saw two solutions in class. A solution using a stack: 
 
function reverse(queue): 
stack = empty stack 
while queue is not empty: 
item = queue.dequeue() 
stack.push(item) 
while stack if not empty: 
item = stack.pop() 
queue.enqueue(item) 
return queue 
 
   
And a solution using recursion: 
 
function reverse(queue): 
if queue is empty: 
return queue 
else: 
item = queue.dequeue() 
queue = reverse(queue) 
queue.enqueue(item) 
return queue 
 
 
c)​ Write an algorithm called​ non_divider w ​ hich takes an integer​ n ​
as 
argument and returns a list with all the positive numbers smaller than​ n ​ which 
do not divide it. 
 
Example: ​non_divider(10) → [3, 4, 6, 7, 8, 9] 
 
function non_divider(n): 
output = [ ] 
for each number from 2 to (n - 1): 
if n % number != 0: 
output.append(number) 
return output 
 
 
d)​ Write an algorithm called​ all_even ​
which takes a list of numbers as 
argument and returns​ True i​f all numbers in the list are even and​ False 
otherwise. 
 
function all_even(numbers): 
for each n in numbers: 
if n % 2 != 0: 
return False 
return True 
 
   
e) W
​ rite an algorithm which returns the average of a list of numbers. Return nil if 
the list is empty. 
 
function average(list_of_numbers): 
length = length of list_of_numbers 
total = 0 
for each n in list_of_numbers: 
total = total + n 
return total / length 
 
f) ​Write an algorithm called​ span w
​ hich takes a list of number as argument and 
returns the difference between the minimum and the maximum in the list. 
Return nil if the list is empty. 
 
function span(list_of_numbers): 
min = list_of_numbers[0] 
max = list_of_numbers[0] 
for each n in list_of_numbers: 
if n < min: 
min = n 
else if n > max: 
max = n 
return max - min 
   
Problem 3 
 
Consider the following tree and answer the questions below. 
 

 
 
a)​ What is the root of the tree? 
 
Life 
 
 
b) W
​ hat is the depth of the tree? 
 

 
c) ​What is the size of the tree? 
 

 
d) W
​ hat are the leaves of the tree? 
 
Dog Cat Bacteria Trees Cactus 
 
e) W
​ hat is a binary tree? And Is this a binary tree? 
 
A binary tree is a tree where each node has at most 
two children. This tree is not a binary tree because 
“Life” has three children. 
 
f) ​What are the children of “Mammals”? 
 
Dog Cat 
 
g) ​Using pseudocode, write down an algorithm called​ print_leaves w ​ hich 
takes the​ root ​of a tree as argument and prints all the leaves of the tree. The 
leaves can be printed in any order you want. 
 
 
Version using Depth-First-Search: 
 
function print_leaves(root): 
if root has no children: 
print root 
else: 
for each child in root.children: 
print_leaves(child) 
 
 
 
Version using Breadth-First-Search 
 
function print_leaves(root): 
queue = empty queue 
queue.enqueue(root) 
while queue is not empty: 
node = queue.dequeue() 
if node has no children: 
print(node) 
else: 
enqueue all node children in queue 
 
   
Problem 4 (20 points) 
 
Consider the following algorithm. 
 
function take_while(list, item): 
output = [ ] 
 
i = 0 
 
while i < (list length) and list[i] != item: 
output.append(list[i]) 
increment i 
 
return output 
 
 
a)​ What is the output after calling the function with the following arguments? 
 
take_while([1, 2, 3, 4], 3) 
 
[1, 2] 
 
b) W
​ hat is the output after calling the function with the following arguments? 
 
take_while([3, 6, 1, 2], 7) 
 
[3, 6, 1, 2] 
 
c)​ If​ list ​
has length​ n ​
in the above algorithm, what is the maximum number 
of operation the function takes before returning? 
 
4n + 3 
 
Anything which looks like the above would be 
accepted. Remember: the exact number do not matter, 
only the dominant term matters. 
 
d)​ What is the time complexity of the algorithm? 
 
O(n)   
Problem 5 
 
Consider the following algorithm. 
 
function increment(list): 
output = [ ] 
 
i = 0 
 
for each element in list: 
output.append(element + i) 
increment i 
 
return output 
 
 
a)​ What is the output after calling the function with the following arguments? 
 
increment([1, 2, 3, 4]) 
 
[1, 3, 5, 7] 
 
b)​ What is the output after calling the function with the following arguments? 
 
increment([4, 3, 2, 1]) 
 
[4, 4, 4, 4] 
 
 
c)​ If​ list ​
has length​ n ​
in the above algorithm, what is the maximum number 
of operation the function takes before returning? 
 
3n + 3 
 
 
d)​ What is the time complexity of the algorithm? 
 
O(n) 
   
Problem 6 
 
For an interview, you are asked to write a P​ ython​ function called 
same_elements ​ with the following properties. 
 
1) The function must take two lists as arguments; 
2) The function must return​ True ​ if both list contain the same elements in 
any order and​ False ​ otherwise; 
3) The function must be at most ​O(n log n)​ . 
 
Examples: 
 
- same_elements([1, 3, 2], [3, 2, 1]) → True 
- same_elements([1, 1, 2], [1, 2, 1]) → True 
- same_elements([1, 6], [4, 2]) → False 
- same_elements([4, 5, 6], []) → False 
 
Write the ​Python​ function​ same_elements​ . Make sure that your code respects 
indentation and Python syntax. 
 
Here is the long way: 
 
def same_elements(list1, list2): 
if len(list1) != len(list2): 
return False 
list1 = sorted(list1) 
list2 = sorted(list2) 
 
for i in range(len(list1)): 
if list1[i] != list2[i]: 
return False 
 
return True 
 
Here is the short O(n log n) way: 
 
def same_elements(list1, list2): 
return sorted(list1) == sorted(list2) 
 
Here is the O(n) way using a hashtable (dictionary): 
 
def same_elements(list1, list2): 
table1 = {} 
table2 = {} 
 
for n in list1: 
if n not in table1: 
table1[n] = 1 
else: 
table[n] += 1 
 
for n in list2: 
if n not in table2: 
table2[n] = 1 
else: 
table2[n] += 1 
 
return table1 == table2 
 
 

You might also like