题目:
给你一个数组 nums 和一个整数 target 。
请你返回 非空不重叠 子数组的最大数目,且每个子数组中数字和都为 target 。
示例 1:
输入:nums = [1,1,1,1,1], target = 2
输出:2
解释:总共有 2 个不重叠子数组(加粗数字表示) [1,1,1,1,1] ,它们的和为目标值 2 。
示例 2:
输入:nums = [-1,3,5,1,4,2,-9], target = 6
输出:2
解释:总共有 3 个子数组和为 6 。
([5,1], [4,2], [3,5,1,4,2,-9]) 但只有前 2 个是不重叠的。
示例 3:
输入:nums = [-2,6,6,3,5,4,1,2,8], target = 10
输出:3
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-number-of-non-overlapping-subarrays-with-sum-equals-target
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
答案:
时间:
10 min
class Solution:
def maxNonOverlapping(self, nums: List[int], target: int) -> int:
n=len(nums)
dp=[0]*(n+1)
prefix=[0]
for num in nums:
prefix.append(prefix[-1]+num)
record={prefix[0]:0}
for i in range(1,n+1):
dp[i]=max(dp[i],dp[i-1])
val= prefix[i]-target
if val in record:
pos=record[val]
dp[i]=max(dp[i],dp[pos]+1)
record[prefix[i]]=i
return dp[-1]
要点:
1. dp 定义:前i个能拆几段
2. 转移方程:
if sum[i:j]=target: dp[i]=max(dp[i],dp[pos]+1)
这里的sum[i:j] 用前缀和表示,这里的pos 是离j最近的一个i(贪心)
3. 更新点
这一个一定比上一个大,dp[i]=max(dp[i],dp[i-1])
更新记录的前缀和,来锁定离 j 最近的 i ,所以是时时更新。