Unit 3 - Notes

CSE408 8 min read

Unit 3: Divide and Conquer and Order Statistics

1. The Divide and Conquer Paradigm

Divide and Conquer is a fundamental algorithm design strategy that works by recursively breaking down a problem into two or more sub-problems of the same or related type, until these become simple enough to be solved directly. The solutions to the sub-problems are then combined to give a solution to the original problem.

  • Divide: Break the given problem into sub-problems of same type.
  • Conquer: Recursively solve these sub-problems.
  • Combine: Appropriately combine the answers.

Merge Sort

  • Algorithm: Divides the unsorted list into sublists, each containing one element (a list of one element is considered sorted). Repeatedly merges sublists to produce new sorted sublists until there is only one sorted list remaining.
  • Recurrence Relation:
  • Time Complexity: Best, Average, and Worst Case:
  • Space Complexity: (Requires auxiliary space for merging).
  • Stability: Stable.

Quick Sort

  • Algorithm: Picks an element as a pivot and partitions the given array around the picked pivot. The elements smaller than the pivot are placed before it, and elements greater are placed after. The subarrays are recursively sorted.
  • Recurrence Relation: (where is the pivot index).
  • Time Complexity:
    • Best/Average Case: (Pivot divides array roughly into halves)
    • Worst Case: (Array is already sorted, and pivot is the smallest/largest element)
  • Space Complexity: average, worst (call stack).
  • Stability: Not stable in its standard form.

Binary Search

  • Algorithm: Searches a sorted array by repeatedly dividing the search interval in half. If the value of the search key is less than the item in the middle of the interval, narrow the interval to the lower half. Otherwise, narrow it to the upper half.
  • Recurrence Relation:
  • Time Complexity: worst and average; best.

Multiplication of Large Integers (Karatsuba Algorithm)

  • Standard Multiplication: Requires bit operations for two -digit numbers.
  • Karatsuba Algorithm: Reduces the multiplication of two -digit numbers to at most $3$ multiplications of -digit numbers (instead of 4).
    • Let and .
    • Compute , , and .
    • .
  • Recurrence Relation:
  • Time Complexity:

Strassen's Matrix Multiplication

  • Standard Method: Multiplying two matrices takes operations.
  • Divide and Conquer (Naive): .
  • Strassen’s Method: Reduces the 8 recursive matrix multiplications to 7 using clever algebraic substitutions.
  • Recurrence Relation:
  • Time Complexity:

Closest-Pair Problem (Divide and Conquer)

  • Problem: Find the two closest points in a set of points in a 2D plane.
  • Algorithm:
    1. Sort points by x-coordinate.
    2. Divide the set into two halves by a vertical line .
    3. Recursively find the minimum distance in both halves, let .
    4. Create a strip of width around the dividing line and find any pair within this strip closer than (requires checking at most 7 neighbors per point if sorted by y-coordinate).
  • Time Complexity:

Convex-Hull Problem (Divide and Conquer / QuickHull)

  • Problem: Find the smallest convex polygon containing all points in a given set.
  • Algorithm (Divide and Conquer): Sort points by x-coordinate, recursively find the convex hull of the left and right halves, and merge the two hulls by finding upper and lower tangents in linear time.
  • Time Complexity: .

2. Solving Recurrences

Recurrences express the running time of a recursive algorithm.

Substitution Method

  1. Guess the form of the solution (e.g., ).
  2. Verify by mathematical induction.
  3. Solve for constants.
    • Use case: When you have a strong intuition about the bound.

Recursion-Tree Method

  1. Draw a tree where nodes represent the cost of a single subproblem.
  2. Sum the costs within each level of the tree.
  3. Sum the per-level costs to determine the total cost.
    • Use case: Great for visualizing and generating a good guess for the substitution method.

Master Method

Provides a cookbook method for solving recurrences of the form: , where .
Compare with :

  • Case 1: If for some , then .
  • Case 2: If for , then .
  • Case 3: If for some and for , then .

3. Decrease and Conquer

A paradigm where you reduce a problem to a smaller instance of the same problem, solve the smaller instance, and extend the solution to the original problem.

Insertion Sort

  • Decrease by one: Assume is sorted. Insert into its correct position to make sorted.
  • Time Complexity: worst/average, best.

Depth-First Search (DFS) and Breadth-First Search (BFS)

  • DFS: Explores as far as possible along each branch before backtracking. Uses a Stack (or recursion).
  • BFS: Explores the neighbor nodes first, before moving to the next level neighbors. Uses a Queue.
  • Time Complexity: for both (using adjacency lists).

Connected Components

  • Using DFS or BFS, we can traverse an undirected graph. Every time we start a new traversal from an unvisited vertex, we discover a new connected component.
  • Time Complexity: .

Topological Sort

  • Problem: Linear ordering of vertices in a Directed Acyclic Graph (DAG) such that for every directed edge , vertex comes before .
  • Algorithm: Perform DFS. When a node finishes exploring all its neighbors (post-order), push it to a stack. Pop the stack to get the topological order. Alternatively, use Kahn's algorithm (in-degree counting).
  • Time Complexity: .

4. Transform and Conquer

Solve a problem by transforming it into a simpler or more convenient instance, or representing it in a different data structure.

Presorting

  • Sorting data before solving a problem can often yield faster algorithms.
  • Examples: Finding element uniqueness ( via presorting vs naive), computing the mode, or finding closest pairs in 1D.

Balanced Search Trees

  • Transforming a list into a balanced BST (like AVL Tree or Red-Black Tree) ensures that Search, Insert, and Delete operations take worst-case time, avoiding the worst-case of unbalanced trees.

Heaps and Heapsort

  • Heap: A nearly complete binary tree satisfying the heap property (Max-Heap or Min-Heap).
  • Heapsort Algorithm:
    1. Build a Max-Heap from the input array ().
    2. Repeatedly swap the root (maximum element) with the last element, reduce heap size, and Heapify the root ( per swap).
  • Time Complexity: (in-place sorting).

Hashing

  • Transforms keys into array indices using a hash function.
  • Allows average time complexity for search, insert, and delete operations.
  • Must handle collisions (e.g., via Chaining or Open Addressing).

5. Order Statistics and Sorting Algorithms

Minimum and Maximum (Simultaneous)

  • Naive: Find min ( comparisons) and max ( comparisons) independently. Total .
  • Optimized: Compare elements in pairs. Compare the larger to the current max, and the smaller to the current min. Total comparisons .

Selection Sort and Bubble Sort

  • Selection Sort: Repeatedly finds the minimum element from the unsorted part and puts it at the beginning. time.
  • Bubble Sort: Repeatedly swaps adjacent elements if they are in the wrong order. time.

Linear Time Sorting Algorithms (Non-Comparison Based)

Comparison-based sorting has a lower bound of . The following sort in linear time under specific conditions:

Counting Sort

  • Concept: Counts the occurrences of each unique element in the input. Assumes elements are integers in a range .
  • Time Complexity: . Stable sort. Used when .

Radix Sort

  • Concept: Sorts elements digit by digit, starting from the least significant digit (LSD) to the most significant digit (MSD), using a stable sub-sort (like Counting Sort).
  • Time Complexity: where is the number of digits and is the base (e.g., 10).

Bucket Sort

  • Concept: Divides the input into several uniformly distributed "buckets." Each bucket is sorted individually (e.g., using Insertion Sort), and then concatenated.
  • Time Complexity: Average if the input is uniformly distributed. Worst-case if all elements hash to the same bucket.