Skip to content

The Maximum Subarray Problem

The Maximum Subarray Problem

Given an array with \(n\) elements, find the subarray where its elements have the maximum sum.

Solution

Divide and Conquer

  • 將陣列對半切,得到\(L,R\)兩個陣列
  • \(L,R\)作遞迴,分別得到\(L\)\(R\)中的最大子陣列\(L_{max}\)\(R_{max}\)
  • 合併時不只比較左右兩邊,還要看有沒有橫跨兩邊且比左右兩邊都大的子列
Code
class SubArrRepr:
    def __init__(self, left: int, right: int, sum: int):
        self.left: int = left
        self.right: int = right
        self.sum: int = sum

    def __gt__(self, rhs):
        return self.sum > rhs.sum

    def __lt__(self, rhs):
        return self.sum < rhs.sum

    def __eq__(self, rhs):
        return self.sum == rhs.sum

    def __repr__(self) -> str:
        return f"{arr[self.left : self.right + 1]}, Sum = {self.sum}"


def divide_and_conquer(arr, left: int, right: int) -> SubArrRepr:
    if left > right:
        return SubArrRepr(left, right, -10000)
    if left == right:
        return SubArrRepr(left, right, arr[left])
    mid = (left + right) // 2
    larr = divide_and_conquer(arr, left, mid)
    rarr = divide_and_conquer(arr, mid + 1, right)

    rightSum = leftSum = -100000

    # go right from element at mid + 1
    sum = 0
    i = mid + 1
    maxRend = i
    while i <= right:
        sum += arr[i]
        if rightSum < sum:
            rightSum = sum
            maxRend = i
        i += 1

    # go left from mid element
    sum = 0
    i = mid
    maxLend = i
    while i >= left:
        sum += arr[i]
        if leftSum < sum:
            leftSum = sum
            maxLend = i
        i -= 1
    return max(larr, rarr, SubArrRepr(maxLend, maxRend, leftSum + rightSum))

Complexity

  • Time Complexity

    對半切再合起來就是\(T(n)=2T(n/2)+f(n)\),合併用的算法是線性所以\(f(n)=\Theta(n)\),長得跟mergesort一模一樣所以就是\(\Theta(n\log n)\)

  • Space Complexity

    需要function call,function call裡面用到常數資源(leftSum, rightSum, i, mid, sum, maxLend, maxRend),function call不重疊,所以總共就是\(\Theta(\log n)\)

Dynamic programming

Code