Divide and Conquer breaks a problem into smaller parts, solves each part, then combines results. What is the main advantage of this approach?
Think about how breaking problems into smaller parts helps with solving them.
Divide and Conquer reduces problem size step-by-step, simplifying complex problems. It does not always guarantee fastest solutions or use less memory, and it often uses recursion.
What is the printed output of the following Java code that shows the divide steps of merge sort on array [4, 3, 2, 1]?
public class MergeSortDivide { public static void divide(int[] arr, int start, int end) { if (start >= end) { System.out.print(arr[start] + " "); return; } int mid = (start + end) / 2; divide(arr, start, mid); divide(arr, mid + 1, end); } public static void main(String[] args) { int[] arr = {4, 3, 2, 1}; divide(arr, 0, arr.length - 1); } }
Focus on the order in which the base cases print elements.
The divide function prints elements when start == end, visiting left half first then right half, so it prints 4 3 2 1 in order.
Given the array [5, 3, 8, 4, 2] and the partition function choosing the last element as pivot, what is the array after one partition call?
public class QuickSortPartition { public static int partition(int[] arr, int low, int high) { int pivot = arr[high]; int i = low - 1; for (int j = low; j < high; j++) { if (arr[j] < pivot) { i++; int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } int temp = arr[i + 1]; arr[i + 1] = arr[high]; arr[high] = temp; return i + 1; } public static void main(String[] args) { int[] arr = {5, 3, 8, 4, 2}; partition(arr, 0, arr.length - 1); for (int num : arr) { System.out.print(num + " "); } } }
Remember the pivot is the last element and elements less than pivot move left.
The pivot is 2 (last element). No elements are less than 2, so 'i' remains -1. The final swap places the pivot at index 0, resulting in the array [2, 3, 8, 4, 5].
What is the error in this Java merge sort code that causes infinite recursion?
public class MergeSortBug { public static void mergeSort(int[] arr, int start, int end) { if (start > end) return; int mid = (start + end) / 2; mergeSort(arr, start, mid); mergeSort(arr, mid + 1, end); // merging code omitted } }
Check when recursion should stop to avoid infinite calls.
The base case must stop recursion when start equals end (single element). Using start > end misses this and causes infinite recursion.
Consider a divide and conquer algorithm that splits a problem of size n into 3 subproblems each of size n/4, and combines results in linear time O(n). What is the time complexity T(n)?
Use the Master Theorem: T(n) = a T(n/b) + f(n), with a=3, b=4, f(n)=O(n).
Here, a=3, b=4, so log_b(a) = log_4(3) ≈ 0.792. Since f(n) = O(n) = O(n^1), and 1 > 0.792, time complexity is O(n).
