Consolidate duplicate implementations of max subarray (#8849)

* Remove max subarray sum duplicate implementations

* updating DIRECTORY.md

* Rename max_sum_contiguous_subsequence.py

* Fix typo in dynamic_programming/max_subarray_sum.py

* Remove duplicate divide and conquer max subarray

* updating DIRECTORY.md

---------

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
Tianyi Zheng
2023-07-11 02:44:12 -07:00
committed by GitHub
parent c9ee6ed188
commit a0eec90466
9 changed files with 174 additions and 313 deletions

View File

@ -1,93 +0,0 @@
"""
author : Mayank Kumar Jha (mk9440)
"""
from __future__ import annotations
def find_max_sub_array(a, low, high):
if low == high:
return low, high, a[low]
else:
mid = (low + high) // 2
left_low, left_high, left_sum = find_max_sub_array(a, low, mid)
right_low, right_high, right_sum = find_max_sub_array(a, mid + 1, high)
cross_left, cross_right, cross_sum = find_max_cross_sum(a, low, mid, high)
if left_sum >= right_sum and left_sum >= cross_sum:
return left_low, left_high, left_sum
elif right_sum >= left_sum and right_sum >= cross_sum:
return right_low, right_high, right_sum
else:
return cross_left, cross_right, cross_sum
def find_max_cross_sum(a, low, mid, high):
left_sum, max_left = -999999999, -1
right_sum, max_right = -999999999, -1
summ = 0
for i in range(mid, low - 1, -1):
summ += a[i]
if summ > left_sum:
left_sum = summ
max_left = i
summ = 0
for i in range(mid + 1, high + 1):
summ += a[i]
if summ > right_sum:
right_sum = summ
max_right = i
return max_left, max_right, (left_sum + right_sum)
def max_sub_array(nums: list[int]) -> int:
"""
Finds the contiguous subarray which has the largest sum and return its sum.
>>> max_sub_array([-2, 1, -3, 4, -1, 2, 1, -5, 4])
6
An empty (sub)array has sum 0.
>>> max_sub_array([])
0
If all elements are negative, the largest subarray would be the empty array,
having the sum 0.
>>> max_sub_array([-1, -2, -3])
0
>>> max_sub_array([5, -2, -3])
5
>>> max_sub_array([31, -41, 59, 26, -53, 58, 97, -93, -23, 84])
187
"""
best = 0
current = 0
for i in nums:
current += i
current = max(current, 0)
best = max(best, current)
return best
if __name__ == "__main__":
"""
A random simulation of this algorithm.
"""
import time
from random import randint
from matplotlib import pyplot as plt
inputs = [10, 100, 1000, 10000, 50000, 100000, 200000, 300000, 400000, 500000]
tim = []
for i in inputs:
li = [randint(1, i) for j in range(i)]
strt = time.time()
(find_max_sub_array(li, 0, len(li) - 1))
end = time.time()
tim.append(end - strt)
print("No of Inputs Time Taken")
for i in range(len(inputs)):
print(inputs[i], "\t\t", tim[i])
plt.plot(inputs, tim)
plt.xlabel("Number of Inputs")
plt.ylabel("Time taken in seconds ")
plt.show()

View File

@ -0,0 +1,60 @@
"""
The maximum subarray sum problem is the task of finding the maximum sum that can be
obtained from a contiguous subarray within a given array of numbers. For example, given
the array [-2, 1, -3, 4, -1, 2, 1, -5, 4], the contiguous subarray with the maximum sum
is [4, -1, 2, 1], so the maximum subarray sum is 6.
Kadane's algorithm is a simple dynamic programming algorithm that solves the maximum
subarray sum problem in O(n) time and O(1) space.
Reference: https://en.wikipedia.org/wiki/Maximum_subarray_problem
"""
from collections.abc import Sequence
def max_subarray_sum(
arr: Sequence[float], allow_empty_subarrays: bool = False
) -> float:
"""
Solves the maximum subarray sum problem using Kadane's algorithm.
:param arr: the given array of numbers
:param allow_empty_subarrays: if True, then the algorithm considers empty subarrays
>>> max_subarray_sum([2, 8, 9])
19
>>> max_subarray_sum([0, 0])
0
>>> max_subarray_sum([-1.0, 0.0, 1.0])
1.0
>>> max_subarray_sum([1, 2, 3, 4, -2])
10
>>> max_subarray_sum([-2, 1, -3, 4, -1, 2, 1, -5, 4])
6
>>> max_subarray_sum([2, 3, -9, 8, -2])
8
>>> max_subarray_sum([-2, -3, -1, -4, -6])
-1
>>> max_subarray_sum([-2, -3, -1, -4, -6], allow_empty_subarrays=True)
0
>>> max_subarray_sum([])
0
"""
if not arr:
return 0
max_sum = 0 if allow_empty_subarrays else float("-inf")
curr_sum = 0.0
for num in arr:
curr_sum = max(0 if allow_empty_subarrays else num, curr_sum + num)
max_sum = max(max_sum, curr_sum)
return max_sum
if __name__ == "__main__":
from doctest import testmod
testmod()
nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
print(f"{max_subarray_sum(nums) = }")

View File

@ -1,20 +0,0 @@
def max_subarray_sum(nums: list) -> int:
"""
>>> max_subarray_sum([6 , 9, -1, 3, -7, -5, 10])
17
"""
if not nums:
return 0
n = len(nums)
res, s, s_pre = nums[0], nums[0], nums[0]
for i in range(1, n):
s = max(nums[i], s_pre + nums[i])
s_pre = s
res = max(res, s)
return res
if __name__ == "__main__":
nums = [6, 9, -1, 3, -7, -5, 10]
print(max_subarray_sum(nums))