描述
给定一个整数数组,找出两个不重叠的子数组A和B,使两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大。
返回这个最大的差值。
子数组最少包含一个数
您在真实的面试中是否遇到过这个题? 是
样例
给出数组[1, 2, -3, 1],返回 6
挑战
时间复杂度为O(n),空间复杂度为O(n)
这一题其实是上一题和上上题的加强版,具体请看:
https://blog.csdn.net/wenqiwenqi123/article/details/81586084
https://blog.csdn.net/wenqiwenqi123/article/details/81631894
思路是类似的,先从左到右遍历数组,保存遍历到每个元素的当前的最大和最小连续子数组的值。然后从右遍历数组,记录同样的最大和最小连续子数组的值;遍历数组比较每种组合的左右最大连续子数组的差值,返回最大的值。
也就是说我们需要记录四个数组:leftmax、leftmin、rightmax、rightmin。
最后得到两个差值:
differ1=左边最大减去右边最小
differ2=右边最大减去左边最小
比较二者,比较高的就是最后的答案。
代码如下:
class Solution:
"""
@param nums: A list of integers
@return: An integer indicate the value of maximum difference between two substrings
"""
def maxDiffSubArrays(self, nums):
# write your code here
if(len(nums)==2):return abs(nums[0]-nums[1])
# dpleftmax、dprightmax数组记录每个位置结尾的子数组最大和
# dpleftmin、dprightmin数组记录每个位置结尾的子数组最小和
# dpleftmax从左到右遍历
dpleftmax=[0 for i in range(len(nums))]
maxp = -99999
sum = 0
for i in range(0, len(nums)):
if (sum < 0):
sum = nums[i]
else:
sum += nums[i]
maxp = max(maxp, sum)
dpleftmax[i] = maxp
# dprightmax从右到左遍历
dprightmax=[0 for i in range(len(nums))]
maxp = -99999
sum = 0
for i in range(len(nums)-1,-1,-1):
if (sum < 0):
sum = nums[i]
else:
sum += nums[i]
maxp = max(maxp, sum)
dprightmax[i] = maxp
# dpleftmin从左到右遍历
dpleftmin = [0 for i in range(len(nums))]
minp = 99999
sum = 0
for i in range(0, len(nums)):
if (sum > 0):
sum = nums[i]
else:
sum += nums[i]
minp = min(minp, sum)
dpleftmin[i] = minp
# dprightmin从右到左遍历
dprightmin = [0 for i in range(len(nums))]
minp = 99999
sum = 0
for i in range(len(nums)-1,-1,-1):
if (sum > 0):
sum = nums[i]
else:
sum += nums[i]
minp = min(minp, sum)
dprightmin[i] = minp
# dpleftmax里存的是每个位置左边子数组最大和,dprightmax里存的是每个位置右边子数组最大和
# 所以最后统计一遍两者之和最大值
maxp=-99999999
for i in range(1,len(dpleftmax)):
sum1=abs(dpleftmax[i-1]-dprightmin[i])
sum2=abs(dpleftmin[i-1]-dprightmax[i])
sum=max(sum1,sum2)
if(sum>maxp):
maxp=sum
return maxp
s=Solution()
print(s.maxDiffSubArrays([1, 2, -3, 1]))