mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-07-05 01:09:40 +08:00
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:
@ -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()
|
60
dynamic_programming/max_subarray_sum.py
Normal file
60
dynamic_programming/max_subarray_sum.py
Normal 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) = }")
|
@ -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))
|
Reference in New Issue
Block a user