1477. 找两个和为目标值且不重叠的子数组 Krains 2020-07-30 09:50:18 动态规划滑动窗口
# 题目链接
# 滑动窗口+动态规划
首先看看能否使用双指针
单调性:在[i, j]
的区间和是小于等于target的条件下,即sum(i,j)>=targetsum(i, j)>=targetsum(i,j)>=target,假设窗口[i, j]
满足条件且是以j结尾的最大区间,如果此时j往后移了一位,因为arr数组所有元素是大于0的,因此sum(i,j+1)>sum(i,j)sum(i, j+1)>sum(i,j)sum(i,j+1)>sum(i,j),如果i往前移动一位,如果此时还满足区间和小于等于target,sum(i−1,j+1)>=targetsum(i-1, j+1)>=targetsum(i−1,j+1)>=target,那么以j结尾的最大区间就应该为[i-1, j]
,此时就与假设条件矛盾了,即满足单调性,可以使用双指针。
如果数组元素都大于0,可以使用双指针,如果可正可负或者有0就不能使用。
如果不能使用双指针,那么可以使用前缀和加哈希的方式快速找到满足条件的区间。
如何选取两个互不重叠的区间且它们长度之和最小呢?
使用f(j)f(j)f(j)表示当前j以及j之前的满足条件的最小区间长度,假如当前区间为[i, j]
,状态更新规则为:
f(j)=min(f(j−1),j−i+1),ifsum(i,j)=targetf(j)=min(f(j-1), j-i+1),if sum(i,j)=target f(j)=min(f(j−1),j−i+1),ifsum(i,j)=target
答案更新规则:
ans=min(ans,f(i−1)+j−i+1)ans=min(ans, f(i-1)+j-i+1) ans=min(ans,f(i−1)+j−i+1)
表示当前以j结尾的满足条件的区间长度与i-1之前的最小的区间长度之和,这样就能满足两个窗口不重叠且长度之和最小。
class Solution {
public int minSumOfLengths(int[] arr, int target) {
int n = arr.length;
int[] dp = new int[n];
// 注意不能设置为最大值,因为相加会溢出
Arrays.fill(dp, Integer.MAX_VALUE / 2);
int ans = Integer.MAX_VALUE;
for(int i = 0, j = 0, sum = 0; j < n; j++){
sum += arr[j];
while(i <= j && sum > target){
sum -= arr[i++];
}
// 找到满足条件的一个区间
if(sum == target){
dp[j] = j - i + 1;
if(i != 0){
ans = Math.min(ans, dp[i-1] + j - i + 1);
}
}
if(j != 0)
dp[j] = Math.min(dp[j], dp[j-1]);
}
return ans > arr.length ? -1 : ans;
}
}
# 复杂度分析
- 时间复杂度:O(n)O(n)O(n),一次扫描
- 空间复杂度:O(n)O(n)O(n),用了一个dp数组
- HDUOJ---1996汉诺塔VI
- HDUOJ---(1995)汉诺塔V
- HDUOJ----(2612)Find a way
- HDUOJ----2512一卡通大冒险
- HDUOJ------(1230)火星A+B
- nyoj-----前缀式计算
- HDUOJ----(4788)Hard Disk Drive
- NYOJ-------笨蛋难题四
- Win平台Web访问白名单设置脚本(IP安全性原则)
- NYOJ-------表达式求值
- HDUOJ----1181 变形课
- 正确的Win主机网站伪静态设置方法
- HDUOJ----(1084)What Is Your Grade?
- HDUOJ------(1272)小希的迷宫
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 在 ASP.NET WebAPI 中使用 DataAnnotations 验证数据
- CSS简笔画:纯CSS绘制一艘邮轮
- NHibernate 多对多映射的数据更新
- 使用 AngularJS 的 $resource 连接 WebAPI Controller
- CentOS7.8下编译muduo库找不到Boost库报错的解决方法
- 使用 OWIN 搭建 OAuth2 服务器
- Hive on spark下insert overwrite partition慢的优化
- 系统学习Lambda表达式
- 一文搞懂 Flink Kafka Consumer 类两阶段提交
- 在 Nowin 下运行 ASP.NET 5 Beta 2
- Bytom侧链Vapor源码浅析-节点出块过程
- Kubernetes Pod OOM 排查日记
- Netty之旅:你想要的NIO知识点,这里都有!
- (数据科学学习手札92)利用query()与eval()优化pandas代码
- Spring Boot 集成 Elasticsearch 实战