MCQ Section
1 questionsMCQ Section
Q1: Multiple Choice Questions (Any Seven) [2 × 7 = 14]
Choose the correct option of the following (any seven only):
Q1(a): Asymptotic Notation
If f(n) = 5n² + 3n, then f(n) is:
- (i) O(n)
- (ii) O(n²) ✓
- (iii) O(n³)
- (iv) O(log n)
Answer: (ii) O(n²)
Solution: The dominant term in 5n² + 3n is 5n², so f(n) = O(n²).
Q1(b): Recurrence Solution
The solution of recurrence T(n) = T(n/2) + 1 is:
- (i) O(n)
- (ii) O(log n) ✓
- (iii) O(n log n)
- (iv) O(1)
Answer: (ii) O(log n)
Solution: By Master theorem: a=1, b=2, f(n)=1. n^(log_b(a)) = n⁰ = 1. Since f(n) = Θ(1), Case 2 gives T(n) = Θ(log n).
Q1(c): Topological Sort
Topological sorting is possible only for:
- (i) Undirected graphs
- (ii) Directed Acyclic Graphs (DAG) ✓
- (iii) Connected graphs
- (iv) Complete graphs
Answer: (ii) Directed Acyclic Graphs (DAG)
Solution: Topological sort requires a linear ordering of vertices such that for every directed edge (u,v), u comes before v. This is only possible if the graph has no cycles.
Q1(d): Stable Sorting
Which of the following sorting algorithms is stable?
- (i) Quick Sort
- (ii) Heap Sort
- (iii) Merge Sort ✓
- (iv) Selection Sort
Answer: (iii) Merge Sort
Solution: Merge Sort preserves the relative order of equal elements, making it a stable sorting algorithm.
Q1(e): Bellman-Ford
Bellman-Ford algorithm can handle:
- (i) Only positive edge weights
- (ii) Negative edge weights ✓
- (iii) Only unweighted graphs
- (iv) None of the above
Answer: (ii) Negative edge weights
Solution: Unlike Dijkstra's algorithm, Bellman-Ford can handle graphs with negative edge weights and can detect negative weight cycles.
Q1(f): Space Complexity
The space complexity of merge sort is:
- (i) O(1)
- (ii) O(log n)
- (iii) O(n) ✓
- (iv) O(n²)
Answer: (iii) O(n)
Solution: Merge sort requires O(n) extra space for the temporary arrays used during the merge operation.
Q1(g): Optimal Substructure
Which property is required by dynamic programming?
- (i) Greedy choice
- (ii) Optimal substructure ✓
- (iii) Random access
- (iv) Binary property
Answer: (ii) Optimal substructure
Solution: Dynamic programming requires optimal substructure (optimal solution contains optimal solutions to subproblems) and overlapping subproblems.
Q1(h): Counting Sort
The time complexity of counting sort for n elements with range k is:
- (i) O(n + k) ✓
- (ii) O(n log n)
- (iii) O(n²)
- (iv) O(k log n)
Answer: (i) O(n + k)
Solution: Counting sort runs in O(n + k) time where n is the number of elements and k is the range of input values. It's a non-comparison based sort.
Q1(i): Amortized Analysis
Amortized analysis is used to:
- (i) Find the worst case of a single operation
- (ii) Find the average time per operation over a sequence of operations ✓
- (iii) Find the best case time
- (iv) Find space complexity
Answer: (ii) Find the average time per operation over a sequence of operations
Solution: Amortized analysis determines the average cost of operations in a sequence, even though some individual operations may be expensive.
Q1(j): Hamiltonian Path
The Hamiltonian path problem is:
- (i) In P
- (ii) NP-Complete ✓
- (iii) Not in NP
- (iv) Solved in O(n²)
Answer: (ii) NP-Complete
Solution: The Hamiltonian path problem (determining if a path visiting each vertex exactly once exists) is a classic NP-Complete problem.
Long Answer Questions
8 questionsLong Answer Questions
Q2: Divide and Conquer [7 + 7 = 14]
(a) Explain the Master Theorem for solving recurrences. Solve: T(n) = 4T(n/2) + n²
Answer:
Master Theorem: For recurrence T(n) = aT(n/b) + f(n), where a ≥ 1, b > 1:
Let c = log_b(a)
Case 1: If f(n) = O(n^(c-ε)) for some ε > 0, then T(n) = Θ(n^c)
Case 2: If f(n) = Θ(n^c · log^k(n)) for k ≥ 0, then T(n) = Θ(n^c · log^(k+1)(n))
Case 3: If f(n) = Ω(n^(c+ε)) for some ε > 0, and af(n/b) ≤ cf(n) for c < 1, then T(n) = Θ(f(n))
Solving T(n) = 4T(n/2) + n²:
Here a = 4, b = 2, f(n) = n² c = log₂(4) = 2
Compare f(n) = n² with n^c = n²: f(n) = Θ(n² · log⁰(n)) → Case 2 with k = 0
T(n) = Θ(n² log n)
(b) Find the maximum and minimum of an array using divide and conquer. Analyze its complexity.
Answer:
Algorithm:
MAX-MIN(A, low, high)
if low = high // one element
return (A[low], A[low])
if high = low + 1 // two elements
if A[low] < A[high]
return (A[high], A[low])
else
return (A[low], A[high])
mid = ⌊(low + high) / 2⌋
(max1, min1) = MAX-MIN(A, low, mid)
(max2, min2) = MAX-MIN(A, mid+1, high)
return (max(max1, max2), min(min1, min2))
Recurrence: T(n) = 2T(n/2) + 2
Number of comparisons:
- T(n) = 2T(n/2) + 2
- T(2) = 1, T(1) = 0
- Solution: T(n) = 3n/2 - 2
Comparison with naive approach:
- Naive: 2(n-1) = 2n - 2 comparisons
- Divide & Conquer: 3n/2 - 2 comparisons
- Savings: n/2 comparisons
Q3: Dynamic Programming [7 + 7 = 14]
(a) Explain the Longest Common Subsequence (LCS) problem and solve it for X = "ABCBDAB" and Y = "BDCAB".
Answer:
LCS Problem: Find the longest subsequence that is common to two sequences.
DP Recurrence:
c[i,j] = 0 if i=0 or j=0
c[i,j] = c[i-1,j-1] + 1 if X[i] = Y[j]
c[i,j] = max(c[i-1,j], c[i,j-1]) if X[i] ≠ Y[j]
DP Table for X = "ABCBDAB", Y = "BDCAB":
| 0 | B | D | C | A | B | |
|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A | 0 | 0 | 0 | 0 | 1 | 1 |
| B | 0 | 1 | 1 | 1 | 1 | 2 |
| C | 0 | 1 | 1 | 2 | 2 | 2 |
| B | 0 | 1 | 1 | 2 | 2 | 3 |
| D | 0 | 1 | 2 | 2 | 2 | 3 |
| A | 0 | 1 | 2 | 2 | 3 | 3 |
| B | 0 | 1 | 2 | 2 | 3 | 4 |
LCS Length = 4 LCS = "BCAB"
Time Complexity: O(m × n), Space: O(m × n)
(b) Explain the Optimal Binary Search Tree problem using dynamic programming.
Answer:
Problem: Given n keys with known search probabilities, construct a BST that minimizes the expected search cost.
DP Formulation:
- e[i,j] = expected cost of searching an optimal BST containing keys kᵢ ... kⱼ
- w[i,j] = sum of probabilities p[i] to p[j]
- e[i,j] = min_{i≤r≤j} {e[i,r-1] + e[r+1,j] + w[i,j]}
Example: Keys k₁=10, k₂=20, k₃=30 with probabilities p₁=0.3, p₂=0.2, p₃=0.5
Base cases: e[i,i-1] = 0 for all i
Length 1:
- e[1,1] = p₁ = 0.3
- e[2,2] = p₂ = 0.2
- e[3,3] = p₃ = 0.5
Length 2:
- e[1,2] = min{e[1,0]+e[2,2]+0.5, e[1,1]+e[3,2]+0.5} = min{0.7, 0.8} = 0.7
- e[2,3] = min{e[2,1]+e[3,3]+0.7, e[2,2]+e[4,3]+0.7} = min{1.2, 0.9} = 0.9
Length 3:
- e[1,3] = min over r=1,2,3
- r=1: 0 + 0.9 + 1.0 = 1.9
- r=2: 0.3 + 0.5 + 1.0 = 1.8
- r=3: 0.7 + 0 + 1.0 = 1.7 ✓
Minimum expected cost = 1.7 with k₃ as root
Q4: Greedy Algorithms [7 + 7 = 14]
(a) Explain the Fractional Knapsack problem and solve it using greedy approach. Items: (value, weight) = {(60,10), (100,20), (120,30)}, Capacity W=50.
Answer:
Fractional Knapsack: Unlike 0/1 knapsack, items can be broken into fractions. Greedy approach works optimally.
Greedy Strategy: Sort items by value-to-weight ratio (value/weight) in decreasing order, then select items greedily.
Given:
| Item | Value | Weight | Value/Weight |
|---|---|---|---|
| 1 | 60 | 10 | 6.0 |
| 2 | 100 | 20 | 5.0 |
| 3 | 120 | 30 | 4.0 |
Sorted by ratio: Item 1 (6.0), Item 2 (5.0), Item 3 (4.0)
Selection:
- Take Item 1 completely: Weight = 10, Value = 60, Remaining = 40
- Take Item 2 completely: Weight = 20, Value = 100, Remaining = 20
- Take Item 3 partially: 20/30 = 2/3 fraction, Value = 120 × 2/3 = 80
Total Value = 60 + 100 + 80 = 240 Total Weight = 10 + 20 + 20 = 50 ✓
(b) Explain Huffman Coding algorithm. Construct Huffman tree for: a:5, b:9, c:12, d:13, e:16, f:45.
Answer:
Huffman Coding: A greedy algorithm for data compression that assigns variable-length prefix-free codes to characters based on frequencies.
Construction for a:5, b:9, c:12, d:13, e:16, f:45:
Step 1: Combine a(5) and b(9) → node(14) Step 2: Combine c(12) and d(13) → node(25) Step 3: Combine node(14) and e(16) → node(30) Step 4: Combine node(25) and node(30) → node(55) Step 5: Combine f(45) and node(55) → root(100)
Huffman Codes:
| Character | Frequency | Code | Bits |
|---|---|---|---|
| f | 45 | 0 | 1 |
| c | 12 | 100 | 3 |
| d | 13 | 101 | 3 |
| a | 5 | 1100 | 4 |
| b | 9 | 1101 | 4 |
| e | 16 | 111 | 3 |
Weighted path length = 45×1 + 12×3 + 13×3 + 5×4 + 9×4 + 16×3 = 45+36+39+20+36+48 = 224 bits
Q5: Graph Algorithms [7 + 7 = 14]
(a) Explain the Bellman-Ford algorithm. How does it detect negative weight cycles?
Answer:
Bellman-Ford Algorithm:
BELLMAN-FORD(G, w, s)
// Initialize
for each vertex v ∈ V
d[v] = ∞
π[v] = NIL
d[s] = 0
// Relax all edges V-1 times
for i = 1 to |V| - 1
for each edge (u,v) ∈ E
if d[v] > d[u] + w(u,v)
d[v] = d[u] + w(u,v)
π[v] = u
// Check for negative weight cycles
for each edge (u,v) ∈ E
if d[v] > d[u] + w(u,v)
return FALSE // Negative cycle detected
return TRUE
Negative Cycle Detection: After V-1 iterations, if any edge can still be relaxed, it means a negative weight cycle exists. This is because in a graph without negative cycles, V-1 iterations are sufficient to find shortest paths (longest simple path has at most V-1 edges).
Time Complexity: O(V × E) Space Complexity: O(V)
(b) Explain DFS and its applications. Show DFS traversal on a sample graph.
Answer:
DFS Algorithm:
DFS(G)
for each vertex u ∈ V
color[u] = WHITE
π[u] = NIL
time = 0
for each vertex u ∈ V
if color[u] = WHITE
DFS-VISIT(u)
DFS-VISIT(u)
time = time + 1
d[u] = time // discovery time
color[u] = GRAY
for each v adjacent to u
if color[v] = WHITE
π[v] = u
DFS-VISIT(v)
color[u] = BLACK
time = time + 1
f[u] = time // finish time
Example: Graph with vertices {A,B,C,D,E} and edges {A→B, A→C, B→D, C→D, D→E}
DFS from A:
- Visit A (d=1), explore B
- Visit B (d=2), explore D
- Visit D (d=3), explore E
- Visit E (d=4), finish E (f=5)
- Finish D (f=6), finish B (f=7)
- Explore C from A
- Visit C (d=8), D already visited
- Finish C (f=9), finish A (f=10)
DFS Order: A → B → D → E → C
Applications:
- Topological sorting
- Cycle detection
- Strongly connected components
- Path finding
- Solving puzzles (mazes)
Q6: String Matching [7 + 7 = 14]
(a) Explain the KMP (Knuth-Morris-Pratt) string matching algorithm. Compute the failure function for pattern "ABABACA".
Answer:
KMP Algorithm: Efficient string matching that avoids redundant comparisons by using a prefix function (failure function).
Failure Function (π): π[i] = length of longest proper prefix of P[1..i] that is also a suffix.
Computing π for P = "ABABACA":
| i | P[1..i] | Longest proper prefix = suffix | π[i] |
|---|---|---|---|
| 1 | A | - | 0 |
| 2 | AB | - | 0 |
| 3 | ABA | A | 1 |
| 4 | ABAB | AB | 2 |
| 5 | ABABA | ABA | 3 |
| 6 | ABABAC | - | 0 |
| 7 | ABABACA | A | 1 |
π = [0, 0, 1, 2, 3, 0, 1]
KMP Matching:
KMP-MATCHER(T, P)
n = |T|, m = |P|
Compute prefix function π
q = 0
for i = 1 to n
while q > 0 and P[q+1] ≠ T[i]
q = π[q]
if P[q+1] = T[i]
q = q + 1
if q = m
print "Match at" i-m
q = π[q]
Time Complexity: O(n + m) — linear time
(b) Compare naive string matching with KMP. When is KMP significantly better?
Answer:
| Feature | Naive | KMP |
|---|---|---|
| Preprocessing | None | O(m) for prefix function |
| Matching time | O((n-m+1)m) | O(n) |
| Worst case | O(nm) | O(n+m) |
| Backtracking | Text pointer backtracks | Text pointer never backtracks |
When KMP is significantly better:
-
Repetitive patterns: When pattern has repeated substrings (e.g., "AAAA"), naive algorithm backtracks many times while KMP uses the prefix function.
-
Repetitive text: Text like "AAAAAAAAB" with pattern "AAAB" — naive does many unnecessary comparisons.
-
DNA/Protein sequences: Biological sequences with limited alphabet (4 or 20 characters) have many partial matches.
-
Large-scale text search: Searching in large documents, log files, or databases where O(nm) is prohibitive.
Example: Text = "AAAAAAAAB", Pattern = "AAAB"
- Naive: Compares AAAB at each position, O(nm) = O(36)
- KMP: Uses prefix function, O(n+m) = O(13)
Q7: Backtracking [7 + 7 = 14]
(a) Solve the Sum of Subsets problem using backtracking for S={1,2,5,6,8} and d=9.
Answer:
Problem: Find all subsets of S whose elements sum to d = 9.
State-space tree exploration with pruning:
Sort S = {1, 2, 5, 6, 8}
Backtracking with bounding:
- Include/exclude each element
- Prune if: current sum > d (exceeded) or current sum + remaining < d (can't reach)
Solutions found:
- {1, 2, 6}: 1 + 2 + 6 = 9 ✓
- {1, 8}: 1 + 8 = 9 ✓
- {3, 6}: Not possible (3 ∉ S)
Wait, let's redo:
- {1, 2, 6}: 1+2+6 = 9 ✓
- {1, 8}: 1+8 = 9 ✓
State-space tree (partial):
Level 0: sum=0
├── Include 1 (sum=1)
│ ├── Include 2 (sum=3)
│ │ ├── Include 5 (sum=8)
│ │ │ ├── Include 6 (sum=14 > 9, PRUNE)
│ │ ├── Exclude 5 (sum=3)
│ │ │ ├── Include 6 (sum=9 ✓ SOLUTION {1,2,6})
│ ├── Exclude 2 (sum=1)
│ │ ├── Include 5 (sum=6)
│ │ │ ├── Include 6 (sum=12 > 9, PRUNE)
│ │ ├── Exclude 5 (sum=1)
│ │ │ ├── Include 6 (sum=7)
│ │ │ │ ├── Include 8 (sum=15 > 9, PRUNE)
│ │ │ ├── Exclude 6 (sum=1)
│ │ │ │ ├── Include 8 (sum=9 ✓ SOLUTION {1,8})
Solutions: {1,2,6} and {1,8}
(b) Explain graph coloring problem using backtracking. Solve for a sample graph with 3 colors.
Answer:
Graph Coloring Problem: Assign m colors to vertices of a graph such that no two adjacent vertices have the same color.
Backtracking Algorithm:
GRAPH-COLOR(k)
// Try to color vertex k
repeat
NextColor(k) // Find next valid color
if color[k] = 0
return // No valid color, backtrack
if k = n
print solution
else
GRAPH-COLOR(k+1)
NextColor(k)
repeat
color[k] = (color[k] + 1) mod (m+1)
if color[k] = 0
return // All colors exhausted
// Check if color is valid
valid = true
for each vertex j adjacent to k
if color[j] = color[k]
valid = false
break
until valid
Example: Graph with 4 vertices, edges: (1,2), (1,3), (2,3), (2,4), (3,4), 3 colors: R, G, B
Solution:
- Vertex 1: R
- Vertex 2: G (adjacent to 1/R, so not R)
- Vertex 3: B (adjacent to 1/R and 2/G, so not R or G)
- Vertex 4: R (adjacent to 2/G and 3/B, so not G or B)
Coloring: {1:R, 2:G, 3:B, 4:R} ✓
Q8: Advanced Topics [7 + 7 = 14]
(a) Explain the Floyd-Warshall algorithm for all-pairs shortest paths.
Answer:
Floyd-Warshall Algorithm: Finds shortest paths between all pairs of vertices using dynamic programming.
Algorithm:
FLOYD-WARSHALL(W)
n = |V|
D⁰ = W // Initialize with edge weights
for k = 1 to n
for i = 1 to n
for j = 1 to n
D^k[i,j] = min(D^(k-1)[i,j], D^(k-1)[i,k] + D^(k-1)[k,j])
return D^n
Key Idea: In iteration k, consider whether using vertex k as an intermediate vertex improves the shortest path from i to j.
Example: 3 vertices, edges: 1→2(3), 1→3(8), 2→3(2), 3→1(5)
D⁰ (initial):
1 2 3
1 [ 0 3 8 ]
2 [ ∞ 0 2 ]
3 [ 5 ∞ 0 ]
D¹ (through vertex 1):
1 2 3
1 [ 0 3 8 ]
2 [ ∞ 0 2 ]
3 [ 5 8 0 ] // 3→2 via 1: 5+3=8
D² (through vertices 1,2):
1 2 3
1 [ 0 3 5 ] // 1→3 via 2: 3+2=5
2 [ ∞ 0 2 ]
3 [ 5 8 0 ]
D³ (through vertices 1,2,3):
1 2 3
1 [ 0 3 5 ]
2 [ 7 0 2 ] // 2→1 via 3: 2+5=7
3 [ 5 8 0 ]
Time Complexity: O(V³), Space: O(V²)
(b) Explain Travelling Salesman Problem. Why is it NP-Hard?
Answer:
Travelling Salesman Problem (TSP): Given n cities and distances between each pair, find the shortest tour that visits every city exactly once and returns to the starting city.
DP Solution (Held-Karp):
- State: (S, i) = minimum cost to visit all cities in set S ending at city i
- C(S, i) = min_{j∈S, j≠i} {C(S-{i}, j) + d(j, i)}
- Time: O(2ⁿ × n²), Space: O(2ⁿ × n)
Why TSP is NP-Hard:
-
Decision version is NP-Complete: Given a distance matrix and a bound B, is there a tour of total length ≤ B? This decision problem is NP-Complete.
-
Reduction from Hamiltonian Cycle: The Hamiltonian cycle problem (known NP-Complete) can be reduced to TSP in polynomial time. Given a graph G, create a distance matrix where d(i,j) = 1 if edge exists, 2 otherwise. A Hamiltonian cycle exists iff there's a tour of length n.
-
No known polynomial-time algorithm: Despite decades of research, no polynomial-time algorithm exists for TSP (unless P = NP).
-
Exponential number of tours: There are (n-1)!/2 possible tours for n cities, making brute force infeasible.
Approximation: For metric TSP (triangle inequality holds):
- Nearest neighbor heuristic: within factor 2 of optimal
- Christofides' algorithm: within factor 1.5 of optimal
Q9: Short Notes (Any Two) [7 × 2 = 14]
(a) Red-Black Trees
Answer:
Red-Black trees are self-balancing BSTs with the following properties:
- Every node is either Red or Black
- Root is always Black
- Every leaf (NIL) is Black
- If a node is Red, both children are Black (no consecutive reds)
- Every path from root to leaf has the same number of black nodes (black-height)
Operations: All in O(log n) time
- Search: Standard BST search
- Insert: Insert as red, fix violations with rotations and recoloring
- Delete: Complex, uses rotations and recoloring
Height bound: h ≤ 2 log₂(n+1)
Advantages:
- Guaranteed O(log n) worst-case operations
- Used in: Java TreeMap, C++ STL map, Linux kernel
(b) Approximation Algorithms
Answer:
Approximation algorithms find near-optimal solutions to NP-Hard problems in polynomial time.
Approximation Ratio (ρ): For minimization: C/C* ≤ ρ(n) For maximization: C*/C ≤ ρ(n) Where C = algorithm's cost, C* = optimal cost
Examples:
-
Vertex Cover (2-approximation): Pick any edge, add both endpoints, remove covered edges. Gives solution ≤ 2 × optimal.
-
TSP (Christofides 1.5-approximation): MST + minimum weight perfect matching on odd-degree vertices. Cost ≤ 1.5 × optimal.
-
Set Cover (ln n approximation): Greedy selection of set covering most uncovered elements.
PTAS (Polynomial Time Approximation Scheme): For any ε > 0, provides (1+ε)-approximation in polynomial time.
(c) Amortized Analysis
Answer:
Amortized analysis finds the average cost per operation over a worst-case sequence of operations.
Methods:
- Aggregate Method: Total cost of n operations / n
- Accounting Method: Assign amortized costs; "save" extra cost for expensive operations
- Potential Method: Define potential function Φ; amortized cost = actual cost + ΔΦ
Example (Dynamic Array Doubling):
- Most insertions: O(1)
- Occasional doubling: O(n) when array is full
- Amortized cost per insertion: O(1)
Proof using accounting: Charge 3 units per insertion. 1 for insertion, 2 saved for future copy when doubling. Total for n insertions = 3n = O(n), so amortized = O(1) per operation.
(d) Network Flow (Ford-Fulkerson)
Answer:
Maximum Flow Problem: Find the maximum flow from source s to sink t in a flow network.
Ford-Fulkerson Method:
- Start with zero flow
- While there exists an augmenting path from s to t in residual graph:
- Find bottleneck (minimum residual capacity) along the path
- Augment flow along the path by bottleneck value
- Return total flow
Key Concepts:
- Residual Graph: Shows remaining capacity on each edge
- Augmenting Path: Path from s to t with positive residual capacity
- Max-Flow Min-Cut Theorem: Maximum flow = Minimum cut capacity
Time Complexity: O(E × |f*|) where f* is max flow value Edmonds-Karp (BFS): O(V × E²)