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;
    }
};
相关推荐
yi0116 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
好想像大佬一样能够ak所有10 小时前
Leetcode35.搜索插入位置
数据结构·算法·leetcode
aqiu11111110 小时前
【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)
c++·算法·leetcode
垆边人似月.14 小时前
华为OD算法题:查找众数及中位数
数据结构·算法·leetcode
CoderYanger15 小时前
一轮复习——F.动态规划模型总结(入门篇)
java·开发语言·数据结构·算法·leetcode·职场和发展·动态规划
浅念-16 小时前
动态规划专题:斐波那契数列模型 + 网格路径DP(LeetCode例题全解析)
笔记·算法·leetcode·面试·职场和发展·动态规划·推荐算法
夏幻灵16 小时前
每日一题:LeetCode 20:有效的括号——栈与哈希映射详解
算法·leetcode·哈希算法
Nil20817 小时前
leetcode 279完全平方数
算法·leetcode·职场和发展
longlongzihan17 小时前
前缀积与后缀积 —— LeetCode 238. 除了自身以外数组的乘积
开发语言·c++·leetcode
All for pursuit.17 小时前
【动态规划-1】121.买卖股票的最佳时机
数据结构·c++·算法·leetcode·动态规划