LeetCode 1546 和为目标值且不重叠的子数组的最大数目

LeetCode 1546 和为目标值且不重叠的子数组的最大数目

🟠 中等偏上

https://leetcode.cn/problems/maximum-number-of-non-overlapping-subarrays-with-sum-equals-target/description/

思路

考虑到 i之前的大子数组的答案和 到 i-1 的大数组的答案,显然, nums[i] 的加入在 i-1 的答案 基础之上多了一种可能:有一个子数组在最右边包含了 nums[i] 。max( dp[i-1] ,1+dp[i-k] )

递归思路

或者递归思路:传入参数0,要么后移1位和当前区分开来,要么后移一个合法组数组。

fun(){
	return max(fun(1),1+fun(k))
	//0~k-1 是一个合法的子数组。
}

代码

for 循环中的 前缀和的更新在末尾,如果放在sum语句之后,[0,0,0] 这个用例会出错,因为本层后面还要用 hash_map ,提前更新导致错误,因此要放到最后。

class Solution {

public:

    int maxNonOverlapping(vector<int>& nums, int target) {

        unordered_map<int,int> hash_map;  // sum,i 包含arr[i-1]不包含 i。

        hash_map[0] = 0;

        int sum = 0;

        vector<int>  dp(nums.size()+1);  //dp[i] 表示到i-1的答案

        dp[0] = 0;

        for(int i = 1;i<=nums.size();i++){

            sum+=nums[i-1];

            if(hash_map.count(sum-target)){

                int index = hash_map[sum-target]-1;

                dp[i] = max(dp[i-1],1+dp[1+index]);

            }else{

                dp[i] = dp[i-1];

            }

            hash_map[sum] = i;

        }

        return dp.back();

    }

};