Data Structure and Algorithm Design II

Module 10

Xingang (Ian) Fang

Sections

  • Dynamic Programming

  • Max Sum Subarray Problem

Dynamic Programming

Xingang (Ian) Fang

Outline

  • Overview

  • Applications

  • Benefit and Challenges

  • Complexity

Overview

  • An algorithmic paradigm

  • Break into overlapping subproblems

  • Only calculate once to avoid repeated work

  • Store the result in a table for future use

Characteristics

  • Optimal substructure

  • Overlapping subproblems

  • Memoization/tabulation

  • Recursive formulation

  • Either top-down or bottom-up

DP Algorithms

  • Enumeration, decision or optimization types of problems

  • Fibonacci numbers

  • Knapsack problem

  • Longest common subsequence

  • Integer partition

  • Coin change

  • Rod cutting

  • Matrix chain multiplication

Quick Exercises:

  • Can you categorize the above problems by their problem types?

  • Why dynamic programming is not a good fit for bin packing problems?

Benefit and Challenges

Benefits

  • Optimal solution

  • Efficiency

  • Versatility

  • Clarity

Challenges

  • Memory usage

  • Identifying subproblems

  • Algorithm design

  • Time complexity

Complexity Analysis

Time Complexity

  • Number of distinct subproblems

  • Work per subproblem

  • Memoization/tabulation overhead

  • Recursive call overhead

Space Complexity

  • number of distinct subproblems

Max Sum Subarray

  • Given an array of integers, find the contiguous subarray with the largest sum. The array can contain both negative and positive values.

  • For array \([-2, -3, 4, -1, -2, 1, 5, -3]\), the contiguous subarray with the largest sum is \([4, -1, -2, 1, 5]\) with sum 7.

  • Many real-life applications

    • Stock market

    • Image processing

    • Bioinformatics

  • Problem type: Optimization

  • Need exact solution

  • Satisfies

    • Optimal substructure

    • Overlapping subproblems

  • Solutions

    • Brute-force \(\Theta(n^2)\)

    • Divide and conquer \(\Theta(n \log n)\)

    • Dynamic Programming (Kadane’s algorithm) \(\Theta(n)\)

Brute-force Solutions

  • Consider all possible subarrays and compute their sums

function brute_force_max_subarray(arr):
  max_sum = -infinity

  for start from 0 to length(arr) - 1:
    sum_of_subarray = 0

    for end from start to length(arr) - 1:
      sum_of_subarray = sum_of_subarray + arr[end]

      if sum_of_subarray > max_sum:
        max_sum = sum_of_subarray

  return max_sum

Divide and Conquer Solution

  • Divide the array into two halves

  • Recursively find the maximum subarray sum in:

    • Left half

    • Right half

    • Crossing the midpoint

function max_subarray(arr, low, high):
  if low == high:
    return arr[low]

  mid = (low + high) / 2
  return max(max_subarray(arr, low, mid),
            max_subarray(arr, mid + 1, high),
            max_crossing_sum(arr, low, mid, high))

Divide and Conquer Solution (cont.)

function max_crossing_sum(arr, low, mid, high):
  left_sum = -infinity
  sum = 0
  for i from mid downto low:
    sum = sum + arr[i]
    if sum > left_sum:
        left_sum = sum

  right_sum = -infinity
  sum = 0
  for j from mid + 1 to high:
    sum = sum + arr[j]
    if sum > right_sum:
        right_sum = sum

  return left_sum + right_sum

Dynamic Programming Solution

  • Kadane’s algorithm

  • Idea: Compute the maximum subarray sum ending at each position

  • At each end position, the maximum subarray sum is either:

    • The maximum subarray sum ending at the previous position plus the current element

    • The current element

  • Scan the array from left to right only once

Dynamic Programming Solution (cont.)

Consider the array \([-2, 1, -3, 4, -1, 2, 1, -5, 4]\):

  • Start with \(current\_max = arr[0] = -2\) and \(global\_max = -2\).

  • At the second element (1), \(current\_max\) is \(max(-2+1, 1)\), which is 1. \(global\_max\) is now \(max(-2, 1)\), which is 1.

  • This process continues, updating \(current\_max\) and \(global\_max\) with each new element.

  • By the end of the array, \(global\_max\) contains the maximum sum, which in this case is 6 from the subarray \([4, -1, 2, 1]\).

Dynamic Programming Solution (cont.)

function kadane_algorithm(arr):
  current_max = global_max = arr[0]

  for index from 1 to length(arr) - 1:
    current_max = max(arr[index], current_max + arr[index])

    global_max = max(global_max, current_max)

  return global_max