Maximum Subarray Problem
You can buy a unit of stock, only one time, then sell it
at a later date
Buy/sell at end of day
Strategy: buy low, sell high
The lowest price may appear after the highest price
Assume you know future prices
Can you maximize profit by buying at lowest price
and selling at highest price?
Buy lowest sell highest
Brute force
How many buy/sell pairs are possible
over n days?
Evaluate each pair and keep track of
maximum
Can we do better?
Transformation
Find sequence of days so that:
the net change from last to first is maximized
Look at the daily change in price
Change on day i: price day i minus price day i-1
We now have an array of changes (numbers),
e.g.
12,-3,-24,20,-3,-16,-23,18,20,-7,12,-5,-22,14,-4,6
Find contiguous subarray with largest sum
maximum subarray
E.g.: buy after day 7, sell after day 11
Brute force again
Trivial if only positive numbers
(assume not)
Need to check O(n2) pairs
For each pair, find the sum
Thus total time is
Divide-and-Conquer
A[low..high]
Divide in the middle:
A[low,mid], A[mid+1,high]
Any subarray A[i,..j] is
(1) Entirely in A[low,mid]
(2) Entirely in A[mid+1,high]
(3) In both
(1) and (2) can be found recursively
Divide-and-Conquer (cont.)
(3) find maximum subarray that
crosses midpoint
Need to find maximum subarrays of the
form
A[i..mid], A[mid+1..j], low <= i, j <= high
Take subarray with largest sum of (1),
(2), (3)
Divide-and-Conquer (cont.)
Find-Max-Cross-Subarray(A,low,mid,high)
left-sum = -
sum = 0
for i = mid downto low
sum = sum + A[i]
if sum > left-sum then
left-sum = sum
max-left = i
right-sum = -
sum = 0
for j = mid+1 to high
sum = sum + A[j]
if sum > right-sum then
right-sum = sum
max-right = j
return (max-left, max-right, left-sum + right-sum)
Time analysis
Find-Max-Cross-Subarray: O(n) time
Two recursive calls on input size n/2
Thus:
T(n) = 2T(n/2) + O(n)
T(n) = O(n log n)