leetcode 1477. 找两个和为目标值且不重叠的子数组 中等

给你一个整数数组 arr 和一个整数值 target

请你在 arr 中找 两个互不重叠的子数组 且它们的和都等于 target 。可能会有多种方案,请你返回满足要求的两个子数组长度和的 最小值

请返回满足要求的最小长度和,如果无法找到这样的两个子数组,请返回 -1

示例 1:

复制代码
输入:arr = [3,2,2,4,3], target = 3
输出:2
解释:只有两个子数组和为 3 ([3] 和 [3])。它们的长度和为 2 。

示例 2:

复制代码
输入:arr = [7,3,4,7], target = 7
输出:2
解释:尽管我们有 3 个互不重叠的子数组和为 7 ([7], [3,4] 和 [7]),但我们会选择第一个和第三个子数组,因为它们的长度和 2 是最小值。

示例 3:

复制代码
输入:arr = [4,3,2,6,2,3,4], target = 6
输出:-1
解释:我们只有一个和为 6 的子数组。

示例 4:

复制代码
输入:arr = [5,5,4,4,5], target = 3
输出:-1
解释:我们无法找到和为 3 的子数组。

示例 5:

复制代码
输入:arr = [3,1,1,1,5,1,2,1], target = 3
输出:3
解释:注意子数组 [1,2] 和 [2,1] 不能成为一个方案因为它们重叠了。

提示:

  • 1 <= arr.length <= 10^5
  • 1 <= arr[i] <= 1000
  • 1 <= target <= 10^8

分析:首先从右往左,用滑动窗口处理出所有和等于 target 的子数组,用一个数组,记录这些子数组的长度与左端点。接着从左往右,枚举第一个子数组的右端点 r,当一个子数组和恰好等于 target 时,用二分查找之前预处理出来的数组中,那些左端点大于 r 的子数组的最小长度。这里二分查找是查找左端点。这样从左往右枚举完所有的子数组,返回最小长度和即可。

cpp 复制代码
class Solution {
public:
    int minSumOfLengths(vector<int>& arr, int target) {
        int n=arr.size(),ans=INT_MAX;
        vector<pair<int,int>>pos;
        for(int i=n-1,l=i,sum=0,len=INT_MAX;i>=0;--i)
        {
            sum+=arr[i];
            while(sum>target)sum-=arr[l--];
            if(sum==target)len=min(len,l-i+1),pos.push_back({i,len});
        }
        int m=pos.size();
        if(m<2)return -1;

        for(int i=0,l=i,sum=0,len_left=INT_MAX;i<n;++i)
        {
            sum+=arr[i];
            while(sum>target)sum-=arr[l++];
            if(sum==target)
            {
                len_left=i-l+1;
                int left=0,right=m,mid;
                while(left<right)
                {
                    mid=(left+right)/2;
                    if(pos[mid].first<=i)right=mid;
                    else ans=min(ans,len_left+pos[mid].second),left=mid+1;
                }
            }
        }
        if(ans==INT_MAX)return -1;
        return ans;
    }
};
相关推荐
hanlin032 小时前
刷题笔记:力扣第144题-二叉树的前序遍历
笔记·算法·leetcode
圣保罗的大教堂3 小时前
leetcode 3629. 通过质数传送到达终点的最少跳跃次数 中等
leetcode
圣保罗的大教堂4 小时前
leetcode 1914. 循环轮转矩阵 中等
leetcode
wabs6665 小时前
关于二叉树【力扣100.相同的树的思考】
数据结构·c++·算法·leetcode·二叉树·递归法
alphaTao5 小时前
LeetCode 每日一题 2026/9/14-2026/9/20
算法·leetcode
hanlin035 小时前
刷题笔记:力扣第560题-和为k的子数组
笔记·算法·leetcode
Navigator_Z18 小时前
LeetCode //C - 1252. Cells with Odd Values in a Matrix
c语言·算法·leetcode
语戚20 小时前
力扣 1621. 大小为K的不重叠线段的数目:动态规划(Java 实现)
java·算法·leetcode·动态规划·力扣·dp
青山木20 小时前
Hot 100 --- 最长有效括号
java·数据结构·算法·leetcode·动态规划