0
0
DSA Cprogramming

Find Maximum Subarray Divide and Conquer in DSA C

Choose your learning style9 modes available
Mental Model
Split the array into two halves, find the best subarray in the left half, right half, and crossing the middle, then pick the best among them.
Analogy: Imagine you want to find the best stretch of road with the most beautiful views on a long trip. You split the trip into two parts, find the best stretch in each part, and also check if the best stretch crosses the middle point between the two parts.
Array: [ -2, 1, -3, 4, -1, 2, 1, -5, 4 ]
Split: [ -2, 1, -3, 4 ] | [ -1, 2, 1, -5, 4 ]
Left max subarray: ?
Right max subarray: ?
Crossing max subarray: ?
Dry Run Walkthrough
Input: array: [-2, 1, -3, 4, -1, 2, 1, -5, 4]
Goal: Find the maximum sum subarray using divide and conquer
Step 1: Split array into left [-2,1,-3,4] and right [-1,2,1,-5,4]
Left: [-2,1,-3,4]
Right: [-1,2,1,-5,4]
Why: Divide problem into smaller parts to solve recursively
Step 2: Find max subarray in left half by splitting again
Left split: [-2,1] and [-3,4]
Why: Keep dividing until base case of single element
Step 3: Base case: max subarray of [-2] is -2, [1] is 1
Max left-left: 1
Max left-right: max subarray of [-3,4]
Why: Single elements are base max subarrays
Step 4: Find max subarray crossing middle in left half: from 1 to 4
Crossing sum: 1 + (-3) + 4 = 2
Why: Check if crossing subarray is better than halves
Step 5: Max subarray in left half is max of left-left (1), left-right (4), crossing (2)
Left max subarray sum = 4 (subarray [4])
Why: Choose best among left parts
Step 6: Find max subarray in right half [-1,2,1,-5,4] similarly
Right max subarray sum = 4 (subarray [4])
Why: Divide and conquer on right half
Step 7: Find max crossing subarray crossing middle of whole array (between 4 and -1)
Crossing sum = max suffix left + max prefix right = (4 + -1 + 2 + 1) = 6
Why: Check subarray crossing middle for max sum
Step 8: Final max subarray is max of left max (4), right max (4), crossing max (6)
Max subarray sum = 6, subarray [4, -1, 2, 1]
Why: Combine results to get final answer
Result:
Final max subarray: 4 -> -1 -> 2 -> 1 -> null with sum 6
Annotated Code
DSA C
#include <stdio.h>
#include <limits.h>

// Function to find max crossing subarray sum
int maxCrossingSum(int arr[], int left, int mid, int right) {
    int sum = 0;
    int left_sum = INT_MIN;
    for (int i = mid; i >= left; i--) {
        sum += arr[i];
        if (sum > left_sum) {
            left_sum = sum; // update max suffix sum on left
        }
    }

    sum = 0;
    int right_sum = INT_MIN;
    for (int i = mid + 1; i <= right; i++) {
        sum += arr[i];
        if (sum > right_sum) {
            right_sum = sum; // update max prefix sum on right
        }
    }

    return left_sum + right_sum; // max crossing sum
}

// Recursive function to find max subarray sum
int maxSubArraySum(int arr[], int left, int right) {
    if (left == right) {
        return arr[left]; // base case single element
    }

    int mid = (left + right) / 2;

    int left_max = maxSubArraySum(arr, left, mid); // max in left half
    int right_max = maxSubArraySum(arr, mid + 1, right); // max in right half
    int cross_max = maxCrossingSum(arr, left, mid, right); // max crossing mid

    // return max of three
    if (left_max >= right_max && left_max >= cross_max) {
        return left_max;
    } else if (right_max >= left_max && right_max >= cross_max) {
        return right_max;
    } else {
        return cross_max;
    }
}

int main() {
    int arr[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
    int n = sizeof(arr) / sizeof(arr[0]);
    int max_sum = maxSubArraySum(arr, 0, n - 1);
    printf("Maximum subarray sum is %d\n", max_sum);
    return 0;
}
if (left == right) { return arr[left]; }
base case: single element max subarray
int mid = (left + right) / 2;
divide array into two halves
int left_max = maxSubArraySum(arr, left, mid);
find max subarray in left half recursively
int right_max = maxSubArraySum(arr, mid + 1, right);
find max subarray in right half recursively
int cross_max = maxCrossingSum(arr, left, mid, right);
find max subarray crossing the middle
return max of left_max, right_max, cross_max;
combine results to get max subarray sum
for (int i = mid; i >= left; i--) { sum += arr[i]; if (sum > left_sum) left_sum = sum; }
find max suffix sum on left side
for (int i = mid + 1; i <= right; i++) { sum += arr[i]; if (sum > right_sum) right_sum = sum; }
find max prefix sum on right side
OutputSuccess
Maximum subarray sum is 6
Complexity Analysis
Time: O(n log n) because the array is divided into halves recursively and each merge step takes O(n) to find crossing sum
Space: O(log n) due to recursion stack depth proportional to log n
vs Alternative: Better than naive O(n^2) approach that checks all subarrays; slower than Kadane's O(n) but uses divide and conquer strategy
Edge Cases
array with single element
returns that element as max subarray sum
DSA C
if (left == right) { return arr[left]; }
array with all negative numbers
returns the largest (least negative) single element
DSA C
if (left == right) { return arr[left]; }
empty array (not handled explicitly)
undefined behavior, input size must be >=1
DSA C
none (caller must ensure non-empty input)
When to Use This Pattern
When asked to find maximum sum subarray and recursion or divide and conquer is suggested, use this pattern to split the problem and combine results efficiently.
Common Mistakes
Mistake: Not correctly calculating the crossing sum by missing max suffix or prefix sums
Fix: Calculate max suffix sum from mid to left and max prefix sum from mid+1 to right carefully
Mistake: Forgetting base case of single element leading to infinite recursion
Fix: Add base case: if left == right return arr[left]
Summary
Finds the maximum sum of any contiguous subarray using divide and conquer.
Use when you want a recursive approach splitting array into halves and combining results.
The key insight is to consider max subarray in left half, right half, and crossing the middle.