题目
https://leetcode.com/problems/maximum-sum-of-two-non-overlapping-subarrays
给定一个数组A,找到其中不相重合的长为M及L的连续子序列,使两个子序列和最大,返回最大和即可
代码
v1.0
- 思路(暴力搜索可以想到的优化点):
- 计算出前后向长为n的子序列内max_m, max_l,然后便利找一下前向+后项一起啥时候最大
- 优化点1:存一个summary数组,以查表代替重复计算的区间和
- 优化点2:前向区间里长为M、L的数组和最大是多少,计算一次保存下来,避免重复查表
- 代码
import collections
class Solution(object):
def calc_summary_value_list(self, A):
summary_value = []
tmp_sum = 0
n = len(A)
for i in range(n):
tmp_sum += A[i]
summary_value.append(tmp_sum)
return summary_value
def calc_max_n_summary(self, A, L, M, summary_dict):
# surpose M<L
n = len(A)
left_index = M-1
max_n_dict = collections.defaultdict(dict)
max_M, max_L = -1, -1
while(left_index < n):
right_index_m = left_index-M+1
right_index_l = left_index-L+1
tmp_L, tmp_M = -1,-1
if(right_index_l>=0):
tmp_L = summary_dict[left_index] - summary_dict[right_index_l] + A[right_index_l]
if(right_index_m>=0):
tmp_M = summary_dict[left_index] - summary_dict[right_index_m] + A[right_index_m]
if tmp_L > max_L:
max_L = tmp_L
if tmp_M > max_M:
max_M = tmp_M
max_n_dict[left_index] = {'M': max_M, 'L':max_L}
#print("left_index:%d: %d, %d"%(left_index, max_M, max_L))
left_index += 1
return max_n_dict
def maxSumTwoNoOverlap(self, A, L, M):
"""
:type A: List[int]
:type L: int
:type M: int
:rtype: int
"""
if L<M:
tmp = M
M = L
L = tmp
n = len(A)
summary_value = self.calc_summary_value_list(A)
#print(summary_value)
pre_order_max_n = self.calc_max_n_summary(A, L, M, summary_value)
A.reverse()
summary_value = self.calc_summary_value_list(A)
post_order_max_n = self.calc_max_n_summary(A, L, M, summary_value)
max_res = -1
for i in range(n):
pre_index = i
post_index = n-(i+1)-1
if pre_index < M-1 or post_index<M-1:
continue
tmp_res = max(pre_order_max_n[pre_index]['M'] + post_order_max_n[post_index]['L'], pre_order_max_n[pre_index]['L'] + post_order_max_n[post_index]['M'])
if tmp_res > max_res:
max_res = tmp_res
return max_res
- 踩的bug
- [i, j]区间和公式计算错误:应为summary_value[j] - summary_value[i] + A[i]
- 知道前后向区间内max_l, max_m后,计算整个数组max_m, max_l公式错误(区间边缘元素重复);应为pre_index = i, post_index = n-(i+1) -1
- 计算区间内max_m, max_l时,计算起始下标有误:应为:left_index > M-1(此时区间长度未达L,因此不存在max_l但是有max_m)而非left_index > L-1
- 借鉴的优化点
- /捂脸,其实只要算一下前向的就好了,直接扩到N,不用分前后向再拼起来,MG
v1.1
-代码