Design & Analysis of Algorithms

2022-23 Solved Paper · Detailed Marks-Wise Solutions

Group A — Very Short Answer Type Questions [ 10 x 1 = 10 Marks ]

1. (i) State True/False: Approximation algorithm guarantees the best quality of solution. [ 1 Mark ]

Answer: False. An approximation algorithm guarantees a solution within a mathematically bounded ratio (the approximation ratio) of the optimal solution, but it does not strictly guarantee finding the absolute optimal (best) solution itself.

1. (ii) State True/False: O(log n) > O(n). [ 1 Mark ]

Answer: False. The logarithmic complexity \(O(\log n)\) grows strictly slower than linear complexity \(O(n)\), meaning \(O(\log n) < O(n)\) for all sufficiently large \(n\).

1. (iii) What is the time complexity of Knapsack algorithm using Greedy method? [ 1 Mark ]

Answer: \(O(n \log n)\). This applies to the Fractional Knapsack problem. Sorting the \(n\) items by their profit-to-weight ratio takes \(O(n \log n)\) time, followed by a linear \(O(n)\) scan to pack the knapsack.

1. (iv) State True/False: Adjacency matrix and Path Matrix are same. [ 1 Mark ]

Answer: False. An adjacency matrix shows only direct single-edge connections between adjacent vertices, whereas a path matrix (or transitive closure matrix) indicates whether a path of any length exists between two vertices.

1. (v) State True/False: Ordered searching algorithm is a Polynomial Algorithm. [ 1 Mark ]

Answer: True. An ordered search (like Binary Search on a sorted array) runs in \(O(\log n)\) time, which is logarithmic. Since \(O(\log n)\) is strictly bounded by polynomials like \(O(n)\), it is considered a polynomial-time algorithm.

1. (vi) State True/False: Brute Force method gives the best quality of solution. [ 1 Mark ]

Answer: True. Because brute force exhaustively evaluates every single candidate solution in the search space without skipping any, it is absolutely guaranteed to find the true optimal (best) solution, despite being highly inefficient.

1. (vii) State True/False: Travelling Salesman Problem is a Non-Polynomial problem. [ 1 Mark ]

Answer: True. The exact TSP is an NP-hard optimization problem, meaning no polynomial-time algorithm (\(O(n^k)\)) is currently known to solve it.

1. (viii) Name one heuristic method of searching. [ 1 Mark ]

Answer: A* Search Algorithm. Other valid answers include Hill Climbing, Simulated Annealing, or Best-First Search, which all use heuristic functions to guess the closest path to the goal.

1. (ix) Best case time complexity of Binary search algorithm is: [ 1 Mark ]

Answer: \(O(1)\). This occurs when the middle element of the array exactly matches the target value on the very first comparison, requiring no further recursive splits.

1. (x) The time complexity of Floyd's algorithm is: [ 1 Mark ]

Answer: \(O(V^3)\) (where \(V\) is the number of vertices in the graph) due to its three nested loops evaluating paths via intermediate vertices.

1. (xi) Backtracking follows ______ traversal technique. [ 1 Mark ]

Answer: Depth-First Search (DFS). It explores paths deeply into the state space tree using recursive stack frames before backtracking upon hitting constraints.

1. (xii) What is spanning tree? [ 1 Mark ]

Answer: A spanning tree is a connected, acyclic subgraph derived from a connected, undirected graph \(G = (V, E)\) that includes absolutely all vertices \(V\) of the graph, utilizing exactly \(|V| - 1\) edges.

Group B — Short Answer Type Questions [ 3 x 5 = 15 Marks ]

2. Write down an algorithm to solve the Job Sequencing with Deadline Problem using Greedy method. What is the time complexity of your algorithm? [ 5 Marks ]

Algorithm Explanation: The objective is to maximize profit by scheduling jobs such that they complete before their respective deadlines. Each job takes 1 unit of time. The greedy strategy works by prioritizing jobs with the highest profit and scheduling them in the latest possible free time slot to keep earlier slots open for other jobs.

JobSequencing(Jobs Array J, Integer n):
    // 1. Sort all jobs descending by profit
    Sort J in descending order of profit
    
    // 2. Find max deadline to size our timeline
    Max_D = 0
    For i = 1 to n:
       Max_D = max(Max_D, J[i].deadline)
       
    // 3. Initialize slots tracking
    Array slot[1..Max_D] initialized to Free
    
    // 4. Greedily assign jobs to slots
    For i = 1 to n:
       // Search for the latest free slot from deadline down to 1
       For j = min(Max_D, J[i].deadline) down to 1:
          If slot[j] is Free:
             slot[j] = J[i] // Lock in job
             Break // Job scheduled, move to next job
             
    Return slot

Time Complexity Analysis:
• Sorting the \(n\) jobs requires \(O(n \log n)\) time.
• The nested loops for scheduling process each of the \(n\) jobs. In the worst-case scenario, the inner loop searches backwards through \(O(n)\) slots, resulting in \(O(n^2)\) time.
• Total Worst-Case Time Complexity: \(O(n^2)\).

3. Find the maximum flow of the following network. Mention each step clearly. [ 5 Marks ]

Based on the provided network graph with nodes 1 (Source) and 6 (Sink), and the corresponding edge capacities: \(1\to4 (27)\), \(1\to2 (24)\), \(2\to4 (6)\), \(2\to3 (10)\), \(2\to6 (8)\), \(4\to5 (18)\), \(4\to3 (15)\), \(5\to6 (18)\), \(3\to6 (8)\).

We systematically trace augmenting paths from source 1 to sink 6 using the Ford-Fulkerson method and update residual capacities.

  1. Augmenting Path 1: \(1 \to 4 \to 5 \to 6\)
    Bottleneck capacity = \(\min(27, 18, 18) = 18\).
    Push Flow = 18.
    Residuals updated: Edge \(1\to4\) drops to 9, \(4\to5\) to 0, \(5\to6\) to 0.
  2. Augmenting Path 2: \(1 \to 2 \to 6\)
    Bottleneck capacity = \(\min(24, 8) = 8\).
    Push Flow = 8.
    Residuals updated: Edge \(1\to2\) drops to 16, \(2\to6\) drops to 0.
  3. Augmenting Path 3: \(1 \to 2 \to 3 \to 6\)
    Bottleneck capacity = \(\min(16, 10, 8) = 8\).
    Push Flow = 8.
    Residuals updated: Edge \(1\to2\) drops to 8, \(2\to3\) drops to 2, \(3\to6\) drops to 0.

Verification: Look at the sink node 6. All edges directly entering the sink (\(5 \to 6\), \(2 \to 6\), and \(3 \to 6\)) now have a residual forward capacity of exactly 0. The cut around the sink is fully saturated. Thus, no further augmenting paths can possibly exist.

Maximum Total Flow = 18 + 8 + 8 = 34

4. Write down an algorithm in Greedy method to find the minimum spanning tree by Prim's algorithm. What is the time complexity of your algorithm? [ 5 Marks ]

Prim's Algorithm maintains a single growing spanning tree. In each step, it greedily selects the minimum weight edge that connects an unvisited vertex to the existing tree.

Prim-MST(Graph G, weights w, root r):
    1. For each vertex u in G.V:
          u.key = Infinity      // Distance to tree
          u.parent = NIL        // MST parent tracking
    
    2. r.key = 0                // Start at root
    3. Initialize Min-Priority Queue Q containing all vertices V
    
    4. While Q is not empty:
          u = Extract-Min(Q)    // Greedily pick closest vertex
          
          For each neighbor v in G.adj[u]:
             // If v is unvisited and edge (u,v) is lighter than current key
             If v is in Q and w(u, v) < v.key:
                v.parent = u
                v.key = w(u, v)
                Decrease-Key(Q, v, w(u, v)) // Update priority queue

Complexity Analysis:
• Initializing the priority queue takes \(O(V)\).
• The Extract-Min operation runs \(V\) times. If a Binary Min-Heap is used, it takes \(O(V \log V)\) total.
• The inner loop checks \(E\) edges total. Decrease-Key runs at most \(E\) times, taking \(O(E \log V)\) total.
Total Time Complexity: \(O(E \log V)\) with a Binary Heap. Using an advanced Fibonacci Heap reduces this to \(O(E + V \log V)\).

5. (a) State Cook's Theorem. (b) Define Clique with example. [ 5 Marks ]

(a) Cook's Theorem (Cook-Levin Theorem): [ 2.5 Marks ]
Cook's theorem definitively states that the Boolean Satisfiability Problem (SAT) is NP-Complete.
It was historically the very first problem mathematically proven to belong to the NP-Complete class. The theorem demonstrated that any problem inside the NP complexity class could be converted (reduced in polynomial time) into a boolean satisfiability formula, laying the entire foundation for proving other problems are NP-Complete via reductions.

(b) Clique Definition & Example: [ 2.5 Marks ]
A Clique in an undirected graph \(G=(V, E)\) is a subset of vertices \(V' \subseteq V\) wherein every distinct pair of vertices is connected by a direct edge. In graph theory terms, the subgraph induced by \(V'\) is a perfectly complete graph.
Example: Imagine a social network graph where vertices are people and edges represent mutual friendships. If Alice, Bob, and Charlie are all mutual friends with one another, the subset {Alice, Bob, Charlie} forms a clique of size 3 (a triangle). Finding the largest such clique in a graph is known as the Maximum Clique Problem, which is NP-Hard.

6. Define the following terms: (i) Brute Force Algorithm, (ii) Approximation Algorithm. [ 5 Marks ]

(i) Brute Force Algorithm:
A brute force algorithm is a straightforward, exhaustive search strategy that systematically enumerates and evaluates every single possible candidate solution in the search space to find the optimal one.
Pros: It is absolutely guaranteed to find the true correct optimal solution if it exists.
Cons: It is notoriously inefficient and usually impractical for large inputs, often resulting in exponential \(O(2^n)\) or factorial \(O(n!)\) time complexities (e.g., trying all paths in the Travelling Salesman Problem).

(ii) Approximation Algorithm:
An approximation algorithm is a fast (polynomial-time) algorithm explicitly designed to find a "good enough", near-optimal solution for complex NP-Hard optimization problems where finding the exact optimal solution would take centuries.
Key Feature: It comes with a strict mathematical proof guaranteeing that the computed solution's quality is within a specific bounded ratio (the approximation ratio) of the true optimal solution (e.g., a 2-approximation algorithm for Vertex Cover guarantees the solution is at worst exactly twice the size of the optimal minimum cover).

Group C — Long Answer Type Questions [ 3 x 15 = 45 Marks ]

7. Trees, Backtracking, and Shortest Paths [ 15 Marks ]

(a) Find the minimum spanning tree using Prim's method from the given graph. Mention each step clearly. [ 6 Marks ]

Edges present in the given graph: \((1,6)[10]\), \((1,2)[28]\), \((6,5)[25]\), \((2,7)[14]\), \((2,3)[16]\), \((7,5)[24]\), \((7,4)[18]\), \((5,4)[22]\), \((3,4)[12]\).

Prim's algorithm tracing, strictly building a connected tree starting from node 1:

  1. Start at vertex 1. Visited = {1}. Available outgoing edges: (1,6)[wt 10], (1,2)[wt 28].
    Pick minimum: Edge (1, 6) with weight 10. Add vertex 6. Visited = {1, 6}.
  2. Available outgoing edges from {1,6}: (1,2)[28], (6,5)[25].
    Pick minimum: Edge (6, 5) with weight 25. Add vertex 5. Visited = {1, 6, 5}.
  3. Available outgoing edges from {1,6,5}: (1,2)[28], (5,7)[24], (5,4)[22].
    Pick minimum: Edge (5, 4) with weight 22. Add vertex 4. Visited = {1, 6, 5, 4}.
  4. Available outgoing edges from {1,6,5,4}: (1,2)[28], (4,3)[12], (4,7)[18], (5,7)[24].
    Pick minimum: Edge (4, 3) with weight 12. Add vertex 3. Visited = {1, 6, 5, 4, 3}.
  5. Available outgoing edges from {1,6,5,4,3}: (1,2)[28], (3,2)[16], (4,7)[18], (5,7)[24].
    Pick minimum: Edge (3, 2) with weight 16. Add vertex 2. Visited = {1, 6, 5, 4, 3, 2}.
  6. Available outgoing edges from {1,6,5,4,3,2}: (2,7)[14], (4,7)[18], (5,7)[24].
    Pick minimum: Edge (2, 7) with weight 14. Add vertex 7. Visited = {1, 6, 5, 4, 3, 2, 7}.

All vertices are visited. Algorithm terminates.

MST Edges Selected: (1,6)[10], (6,5)[25], (5,4)[22], (4,3)[12], (3,2)[16], (2,7)[14]
Total MST Weight: 10 + 25 + 22 + 12 + 16 + 14 = 99

(b) Write an algorithm to find all solutions of N-Queens problem using backtracking. [ 4 Marks ]

The goal is to place \(N\) queens on an \(N \times N\) chessboard so that no two queens attack each other (no shared row, column, or diagonal).

SolveNQueens(row, N, board[]):
    // Base Case: All N queens are successfully placed
    If row == N:
       Print board state (Solution found)
       Return
       
    // Try placing a queen in each column of the current row
    For col = 0 to N-1:
       If IsSafe(row, col, board, N):
          board[row] = col // Place Queen at (row, col)
          
          // Recur to place the rest of the queens
          SolveNQueens(row + 1, N, board)
          
          // Backtrack: Remove queen (implicitly done by overwriting in next iteration, 
          // or explicitly setting board[row] = -1)

(c) What is the time complexity of your algorithm? [ 1 Mark ]

The worst-case time complexity is \(O(N!)\) (Factorial time), as there are \(N\) choices for the first row, at most \(N-2\) valid choices for the second row, and so on, bounding the search space depth.


(d) Write an algorithm to find all pairs shortest path using Floyd's method. [ 4 Marks ]
Floyd-Warshall(WeightMatrix W, Integer V):
    Initialize DistanceMatrix D^(0) = W
    
    // k is the intermediate vertex being considered
    For k = 1 to V:
       For i = 1 to V:
          For j = 1 to V:
             // Update shortest path if path via k is better
             D^(k)[i][j] = min( D^(k-1)[i][j], D^(k-1)[i][k] + D^(k-1)[k][j] )
             
    Return D^(V)

8. Quick Sort Algorithm and Complexity [ 15 Marks ]

(a) Write down an algorithm of Quick Sort. [ 5 Marks ]
QuickSort(Array A, Integer low, Integer high):
    If low < high:
       // Partition the array and get the pivot index
       p = Partition(A, low, high)
       
       // Recursively sort elements before and after pivot
       QuickSort(A, low, p - 1)
       QuickSort(A, p + 1, high)

Partition(Array A, Integer low, Integer high):
    pivot = A[high] // Pick last element as pivot
    i = low - 1     // Index of smaller element
    
    For j = low to high - 1:
       If A[j] <= pivot:
          i = i + 1
          Swap A[i] with A[j]
          
    // Place pivot in correct sorted position
    Swap A[i+1] with A[high]
    Return i + 1

(b) Derive the best, worst and average case time complexity of your algorithm. [ 10 Marks ]
  • Best Case (\(O(n \log n)\)): [ 2 Marks ]
    Occurs when the pivot consistently partitions the array into exactly two equal halves.
    Recurrence: \(T(n) = 2T(n/2) + cn\).
    Solving via Master's Theorem (Case 2): \(T(n) = \Theta(n \log n)\).

  • Worst Case (\(O(n^2)\)): [ 3 Marks ]
    Occurs when the pivot consistently partitions the array into highly unbalanced subarrays of size 0 and \(n-1\). This happens when the array is already sorted (ascending or descending) and the last element is picked as the pivot.
    Recurrence: \(T(n) = T(n-1) + cn\).
    Expanding: \(T(n) = cn + c(n-1) + c(n-2) + \dots + c \approx c \frac{n^2}{2}\).
    Solving: \(T(n) = \Theta(n^2)\).

  • Average Case (\(O(n \log n)\)): [ 5 Marks ]
    Assuming elements are randomly distributed, the pivot will land anywhere in the array with equal probability \(1/n\). The expected time is the average of all possible partition splits.
    Recurrence: \(T(n) = \frac{1}{n} \sum_{k=0}^{n-1} [T(k) + T(n-k-1)] + cn\)
    By symmetry, this simplifies to: \(T(n) = \frac{2}{n} \sum_{k=0}^{n-1} T(k) + cn\).
    Multiplying by \(n\): \(n T(n) = 2 \sum_{k=0}^{n-1} T(k) + cn^2\) --- (Eq 1)
    Substituting for \(n-1\): \((n-1) T(n-1) = 2 \sum_{k=0}^{n-2} T(k) + c(n-1)^2\) --- (Eq 2)
    Subtracting Eq 2 from Eq 1: \(n T(n) - (n-1) T(n-1) = 2 T(n-1) + 2cn\).
    Rearranging: \(n T(n) = (n+1) T(n-1) + 2cn\).
    Dividing by \(n(n+1)\): \(\frac{T(n)}{n+1} = \frac{T(n-1)}{n} + \frac{2c}{n+1}\).
    Unrolling this telescoping sum yields a harmonic series: \(\frac{T(n)}{n+1} = 2c \sum_{i=1}^{n} \frac{1}{i+1} \approx 2c \ln n\).
    Thus, \(T(n) = \Theta(n \log n)\).

9. Matrix Chain Multiplication & Greedy Strategies [ 15 Marks ]

(a) Find the minimum number of scalar operation needed to multiply the matrices A1(30x35), A2(35x15), A3(15x5) and A4(5x10). [ 5 Marks ]

The dimensions array is \(P = [30, 35, 15, 5, 10]\). The DP recurrence calculates the minimum cost: \(m[i, j] = \min \{m[i, k] + m[k+1, j] + P[i-1] \cdot P[k] \cdot P[j]\}\).

DP Tracing:

  • Chain Length 1: \(m[1,1]=m[2,2]=m[3,3]=m[4,4]=0\).
  • Chain Length 2:
    \(m[1, 2] = 30 \times 35 \times 15 = 15,750\)
    \(m[2, 3] = 35 \times 15 \times 5 = 2,625\)
    \(m[3, 4] = 15 \times 5 \times 10 = 750\)
  • Chain Length 3:
    \(m[1, 3] = \min(m[1,1]+m[2,3]+30\cdot35\cdot5, m[1,2]+m[3,3]+30\cdot15\cdot5)\)
    \(m[1, 3] = \min(0+2625+5250, 15750+0+2250) = \min(7875, 18000) = 7,875\).
    \(m[2, 4] = \min(m[2,2]+m[3,4]+35\cdot15\cdot10, m[2,3]+m[4,4]+35\cdot5\cdot10)\)
    \(m[2, 4] = \min(0+750+5250, 2625+0+1750) = \min(6000, 4375) = 4,375\).
  • Chain Length 4 (Finding \(m[1, 4]\)):
    Split \(k=1\): \(m[1,1] + m[2,4] + 30\cdot35\cdot10 = 0 + 4375 + 10500 = 14,875\).
    Split \(k=2\): \(m[1,2] + m[3,4] + 30\cdot15\cdot10 = 15750 + 750 + 4500 = 21,000\).
    Split \(k=3\): \(m[1,3] + m[4,4] + 30\cdot5\cdot10 = 7875 + 0 + 1500 = 9,375\).
    Minimum cost is 9,375.
Minimum Scalar Multiplications: 9,375
Optimal Parenthesization: \((A_1 \times (A_2 \times A_3)) \times A_4\)

(b) Write down an algorithm using Greedy method to find minimum spanning tree by Kruskal's algorithm. [ 5 Marks ]
Kruskal-MST(Graph G, weights w):
    1. Initialize empty set A = { }
    2. // Create disjoint sets for each vertex
       For each vertex v in G.V:
          Make-Set(v)
          
    3. Sort the edges of G.E in non-decreasing order of weight w
    
    4. // Greedily add edges without forming cycles
       For each edge (u, v) in the sorted G.E:
          // Check if u and v are in different disjoint sets
          If Find-Set(u) != Find-Set(v):
             Add edge (u, v) to set A
             Union(u, v) // Merge the two sets
             
    5. Return A

(c) Find the time complexity of your algorithm. [ 3 Marks ]

Sorting the edges dominates the complexity, taking \(O(E \log E)\) time. The disjoint-set operations (Find and Union) using union-by-rank and path compression take \(O(E \cdot \alpha(V))\) time, where \(\alpha\) is the inverse Ackermann function (effectively constant). Thus, the total time complexity is \(O(E \log E)\), which is equivalent to \(O(E \log V)\).


(d) Differentiate between Backtracking and Branch and Bound. [ 2 Marks ]

Backtracking applies Depth-First Search (DFS) to find all feasible solutions to decision or constraint satisfaction problems, maintaining low memory overhead \(O(V)\). Branch and Bound applies Breadth-First or Best-First Search (BFS) to solve optimization problems by calculating bounds to aggressively prune non-optimal branches, but requires exponentially more memory to store the active search frontier queues.

10. Graph Theory Concepts [ 15 Marks ]

(a) Find the transitive closure of vertex A from the following graph. [ 3 Marks ]

Based on the provided directed graph edges: \(A \to B, A \to C, B \to E, C \to D, D \to H, H \to G, G \to E, E \to F, F \to A, F \to G\).

We trace all vertices reachable from node A using a Depth-First Search (DFS) reachability sequence:

  1. Start at A.
  2. Traverse \(A \to B\) \(\implies\) Reach B.
  3. Traverse \(B \to E\) \(\implies\) Reach E.
  4. Traverse \(E \to F\) \(\implies\) Reach F.
  5. Traverse \(F \to G\) \(\implies\) Reach G. (Note: \(F \to A\) loops back to start, \(G \to E\) loops back to E).
  6. Backtrack to A and traverse the other branch: \(A \to C\) \(\implies\) Reach C.
  7. Traverse \(C \to D\) \(\implies\) Reach D.
  8. Traverse \(D \to H\) \(\implies\) Reach H.
  9. Traverse \(H \to G\) (G is already reached).

Through these paths, node A can successfully reach every single vertex in the graph.

Transitive Closure of Vertex A: {A, B, C, D, E, F, G, H}

(b) Define the following terms: [ 12 Marks ]
  • (i) Directed graph: A graph where the edges have a strict direction, represented as ordered pairs of vertices \((u, v)\), meaning traversal is only allowed from \(u\) to \(v\).
  • (ii) Undirected graph: A graph where edges represent bidirectional connections, modeled as unordered pairs of vertices \(\{u, v\}\), allowing traversal in both directions equally.
  • (iii) In-Degree and Out-Degree: The In-Degree of a vertex is the total number of incoming edges pointing directly into it. The Out-Degree is the total number of outgoing edges pointing away from it.
  • (iv) Complete Graph: A specialized undirected graph where every single distinct pair of vertices is connected by a unique direct edge. It has exactly \(\frac{n(n-1)}{2}\) edges.
  • (v) Articulation Point (Cut Vertex): A critical vulnerability vertex in a connected graph whose complete removal (along with its incident edges) disconnects the graph into two or more independent connected components.
  • (vi) Bridge (Cut Edge): A critical vulnerability edge in a connected graph whose deletion strictly increases the number of connected components in the graph (splitting the graph).

11. Recursion, Master's Theorem, and Asymptotic Notations [ 15 Marks ]

(a) Differentiate between recursion and iteration. [ 3 Marks ]

Recursion is a functional approach where a problem is solved by a function repeatedly calling itself on smaller instances of the input. It utilizes the system call stack memory, making the code elegant and mathematically expressive, but susceptible to stack overflow and overhead delays. Iteration is an imperative approach that uses loop constructs (for, while) to repeat execution blocks. It uses a fixed, constant \(O(1)\) memory footprint and is generally faster due to avoiding call stack overhead.


(b) Find the time complexity of the following recurrence relations using Master's Theorem. [ 8 Marks ]

(i) \(T(n) = 2T(n/4) + n^{0.51}\) [ 4 Marks ]
Comparing to \(T(n) = aT(n/b) + f(n)\): \(a=2, b=4\).
Calculate critical exponent: \(n^{\log_b a} = n^{\log_4 2} = n^{0.5}\).
Compare \(f(n) = n^{0.51}\) with \(n^{0.5}\). Since \(0.51 > 0.5\), \(f(n)\) grows polynomially faster: \(f(n) = \Omega(n^{0.5 + \epsilon})\) with \(\epsilon = 0.01\).
Check the Regularity Condition for Case 3: \(a f(n/b) \le c f(n)\) for \(c < 1\).
\(2 (n/4)^{0.51} = 2 \times 4^{-0.51} \times n^{0.51} \approx 2 \times 0.493 \times n^{0.51} = 0.986 n^{0.51}\).
Since \(0.986 \le c < 1\), the condition is satisfied. This falls strictly into Case 3.
Complexity: \(T(n) = \Theta(f(n)) = \Theta(n^{0.51})\).

(ii) \(T(n) = \sqrt{2} T(n/2) + \log n\) [ 4 Marks ]
Here, \(a=\sqrt{2}, b=2\).
Calculate critical exponent: \(n^{\log_b a} = n^{\log_2 \sqrt{2}} = n^{0.5} = \sqrt{n}\).
Compare \(f(n) = \log n\) with \(n^{0.5}\). The logarithmic function grows strictly polynomially slower than the square root function. Formally, \(f(n) = O(n^{0.5 - \epsilon})\) holds true (for instance, choosing \(\epsilon = 0.1\), \(\log n = O(n^{0.4})\)).
This matches Case 1 of the Master's Theorem.
Complexity: \(T(n) = \Theta(n^{\log_b a}) = \Theta(n^{0.5}) = \Theta(\sqrt{n})\).


(c) Define little omega notation. Explain with an example. [ 4 Marks ]

Little Omega (\(\omega\)) Notation provides an asymptotic, strictly loose lower bound for an algorithm's running time. While Big-\(\Omega\) allows the bounds to be asymptotically tight (grow at the exact same rate), little-\(\omega\) strictly requires the algorithm's time complexity to grow infinitely faster than the bounding function as \(n \to \infty\).

Formally, \(f(n) = \omega(g(n))\) if for any arbitrarily large positive constant \(c > 0\), there exists a threshold \(n_0\) such that \(f(n) > c \cdot g(n) \ge 0\) for all \(n \ge n_0\). This guarantees that:

\[\lim_{n \to \infty} \frac{f(n)}{g(n)} = \infty\]

Example: Prove that \(f(n) = n^2 = \omega(n)\).
Evaluating the limit: \(\lim_{n \to \infty} \frac{n^2}{n} = \lim_{n \to \infty} n = \infty\).
Since the limit evaluates to infinity, it proves that \(n^2\) grows strictly faster than \(n\), validating \(n^2 = \omega(n)\).