• [每日一题2020.06.16] leetcode双周赛T3 5423 找两个和为目标值且不重叠的子数组 DP, 前缀和


    题目链接

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

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

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

    一个map用来保存从0-index i 的前缀和以及索引 ------mp[前缀和] = 索引

    一个dp用来保存不大于目前索引i的最小长度的子数组长度, 如果不存在, 则为maxn

    用一个sum做累加, 同时对map进行更新

    可知当mp中含有sum - target时可以找到一个子数组

    设置cur = 找到的新子数组长度

    bfindex = 此数组之前的(与之不重叠的) 序号

    1592108705114

    则可以由是否存在dp[bfindex]判断此前是否已经有符合条件的数组

    如果有:

    [ans = min (ans, cur + dp[bfindex]) ]

    不管有没有 :

    [dp[i] = min(dp[i-1], cur) ]

    注意当i==0的特殊情况, 不然会造成数组访问越界, 这里我用了个if判断

    ac代码 :

    int minSumOfLengths(vector<int>& arr, int target) {
    	const int maxn = 0x3f3f3f3f;
    	int n = arr.size();
    	int sum = 0;
    	int ans = maxn;
    	vector<int> dp(n, maxn);
    	map<int, int> mp;
    	mp[0] = -1;
    	for (int i = 0; i < n; ++i)
    	{
    		sum += arr[i];
    		
    		if(i)
    			dp[i] = dp[i - 1];
    		if (mp.count(sum - target)) { 
    			int cur = i - mp[sum - target];
    			int bfindex = mp[sum - target];
    			if (bfindex >= 0 && dp[bfindex] < maxn) {
    				ans = min(ans, cur + dp[bfindex]);
    			} 
    			if(i)
    				dp[i] = min(dp[i-1], cur);
    			else
    				dp[i] = min(cur, maxn);
    		}
    		mp[sum] = i;
    	}
    	return ans == maxn ? -1 : ans;
    }
    
  • 相关阅读:
    AMap公交线路查询
    AMap行政区查询服务
    使用JavaScript的Join方法
    获取layer.open弹出层的返回值
    MVC项目中WebViewPage的实战应用
    ASP.NET管道
    Android接收系统广播
    python字符串转换成数字
    mysql缓存
    两个矩阵对应位置的数据相加,并返回一个矩阵
  • 原文地址:https://www.cnblogs.com/roccoshi/p/13124380.html
Copyright © 2020-2023  润新知