"""Kadane's algorithm: maximum subarray sum. Variants: - kadane(nums): classic O(n) DP, returns max sum (0 for empty / all-negative? no — returns max element for all-negative by default; empty list -> 0). - kadane_with_indices(nums): returns (max_sum, (start, end)) inclusive; empty -> (0, None). - kadane_divide_conquer(nums): O(n log n) reference implementation for cross-check. - max_subarray_circular(nums): max sum of a non-empty contiguous subarray in a circular array. """ from typing import List, Optional, Tuple def kadane(nums: List[int]) -> int: if not nums: return 0 best = cur = nums[0] for x in nums[1:]: cur = x if cur < 0 else cur + x # equivalent: cur = max(x, cur + x) if cur > best: best = cur return best def kadane_with_indices(nums: List[int]) -> Tuple[int, Optional[Tuple[int, int]]]: if not nums: return 0, None best = cur = nums[0] best_l = best_r = 0 cur_l = 0 for i, x in enumerate(nums[1:], start=1): if cur < 0: cur = x cur_l = i else: cur += x if cur > best: best = cur best_l = cur_l best_r = i return best, (best_l, best_r) def kadane_divide_conquer(nums: List[int]) -> int: if not nums: return 0 # returns (total, best_prefix, best_suffix, best_sub) def rec(lo, hi): if lo == hi: v = nums[lo] return v, v, v, v mid = (lo + hi) // 2 lt, lp, ls, lb = rec(lo, mid) rt, rp, rs, rb = rec(mid + 1, hi) total = lt + rt prefix = max(lp, lt + rp) suffix = max(rs, rt + ls) best = max(lb, rb, ls + rp) return total, prefix, suffix, best return rec(0, len(nums) - 1)[3] def max_subarray_circular(nums: List[int]) -> int: if not nums: return 0 if len(nums) == 1: return nums[0] # max of (normal kadane) and (total - min_subarray), but not all elements excluded total = sum(nums) # min subarray (non-empty, non-whole? standard: min subarray can be whole -> circular empty; handle) min_ending = min_so_far = nums[0] for x in nums[1:]: min_ending = min(x, min_ending + x) min_so_far = min(min_so_far, min_ending) # if all elements positive, min_subarray == total -> circular would be 0 (empty); use normal circ = total - min_so_far normal = kadane(nums) if circ == 0: return normal return max(normal, circ)