[每日一题2020.06.16] leetcode双周赛T3 5423 找两个和为目标值且不重叠的子数组 DP, 前缀和
2024-10-07 08:07:31
给你一个整数数组 arr 和一个整数值 target 。
请你在 arr 中找 两个互不重叠的子数组 且它们的和都等于 target 。可能会有多种方案,请你返回满足要求的两个子数组长度和的 最小值 。
请返回满足要求的最小长度和,如果无法找到这样的两个子数组,请返回 -1 。
一个map用来保存从0-index i 的前缀和以及索引 ------mp[前缀和] = 索引
一个dp用来保存不大于目前索引i的最小长度的子数组长度, 如果不存在, 则为maxn
用一个sum做累加, 同时对map进行更新
可知当mp中含有sum - target时可以找到一个子数组
设置cur = 找到的新子数组长度
bfindex = 此数组之前的(与之不重叠的) 序号
则可以由是否存在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;
}
最新文章
- discuz X3.1 源代码阅读,记录代码片段
- HTML5的全新语义化元素
- Hibernate设置自增
- Selenium Grid 学习笔记
- [SQL]分组排练进行更新
- 【技术贴】解决Mysql启动服务报错1067 进程意外终止
- Unity入门
- GOPS2017全球运维大会深圳站 出席嘉宾盘点!
- 一点公益二码公益开发模式系统源码App
- Java关键字transient和volatile小结(转)
- MySQL登录汇总
- INV_TXN_MANAGER_PUB.PROCESS_TRANSACTIONS
- How to mount EFI on macOS
- Java笔试面试题整理第六波(修正版)
- angular.js--------demo1
- ASP.Net 获取Form表单值
- openvas漏洞扫描
- CF903G Yet Another Maxflow Problem
- Greengenes Database(16S)
- Lunar New Year and Red Envelopes CodeForces - 1106E (dp)