文章目录
4.1最大子数组
按照书中分治思想的代码:
def find_max_crossing_subarray(A, low, high):
left_sum = -float('inf')
S_left = 0
mid = (low + high) // 2
for i in range(mid, low - 1, -1):
S_left = S_left + A[i]
if S_left > left_sum:
left_sum = S_left
max_left = i
right_sum = -float('inf')
S_right = 0
for j in range(mid + 1, high + 1):
S_right = S_right + A[j]
if S_right > right_sum:
right_sum = S_right
max_right = j
return max_left, max_right, (left_sum + right_sum)
def find_maximum_subarray(A, low, high):
if high == low:
return low, high, A[low]
else:
mid = (low + high) // 2
lft_low, lft_high, lft_sum = find_max_crossing_subarray(A, low, mid)
right_low, right_high, right_sum = find_max_crossing_subarray(A, mid + 1, high)
cross_low, cross_high, cross_sum = find_max_crossing_subarray(A, low, high)
if lft_sum > right_sum and lft_sum > cross_sum:
return lft_low, lft_high, lft_sum
elif right_sum > lft_sum and right_sum > cross_sum:
return right_low, right_high, right_sum
else:
return cross_low, cross_high, cross_sum
A = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7]
print(find_maximum_subarray(A, 0, 15))
print(find_max_crossing_subarray(A, 0, 15))
B = [-4, -2, -1, -5,-1,-6,-7]
print(find_maximum_subarray(B, 0, 6))
采用动态规划思想的:
# 动态规划
def maxSubArray(nums):
S = nums[0]
MAX = S
for i in range(1, len(nums)):
if S > 0: # 如果前面的连续和大于零,就从前面的连续和加上nums[i]和nums[i]中作比较取大的
S += nums[i] # 无论nums[i]是正还是负都先加上,因为不知道nums[i]之后的数据的情况
MAX = max(S, MAX)
else: # 如果前面的连续和小于0 就从前面的最大值 和nums[i]中取大的
S = nums[i]
MAX = max(S, MAX)
return MAX
A = [8, -7, -5]
print(maxSubArray(A))
4.1-1
连续两个元素最大和
4.1-2
暴力求解
# 暴力求解
def maxSubArray(nums):
n = len(nums)
max_sum = -float('inf')
for i in range(n):
S = 0
for j in range(i,n):
S = S + A[j]
if S > max_sum:
max_sum = S
low = i
high = j
return low, high, max_sum
A = [8, -7, -5, 90]
print(maxSubArray(A))
4.1-4
负数情况返回空集
def find_max_crossing_subarray(A, low, high):
left_sum = -float('inf')
S_left = 0
mid = (low + high