当前位置: 首页 > news >正文

动态规划--Day05--最大子数组和--53. 最大子数组和,2606. 找到最大开销的子字符串,1749. 任意子数组和的绝对值的最大值

动态规划–Day05–最大子数组和–53. 最大子数组和,2606. 找到最大开销的子字符串,1749. 任意子数组和的绝对值的最大值

今天要训练的题目类型是:【最大子数组和】,题单来自@灵艾山茶府。

掌握动态规划(DP)是没有捷径的,咱们唯一能做的,就是投入时间猛猛刷题。

动态规划要至少刷100道才算入门!

53. 最大子数组和

思路【我】:

  • 情况一:如果累加和已经负数了,再把它加到f[i],只会让f[i]更小。此时直接从f[i]开始累加。
  • 情况二:else,直接累加
  • f[i]只表示,这一段的最大子数组和。不是全局的最大子数组和。所以要用res记录全局最大值。
class Solution {public int maxSubArray(int[] nums) {int n = nums.length;int[] f = new int[n];// 初始化f[0] = nums[0];int res = nums[0];// 从1开始从前往后for (int i = 1; i < n; i++) {// 如果累加和已经负数了,再把它加到f[i],只会让f[i]更小// 此时直接从f[i]开始累加if (f[i - 1] < 0) {f[i] = nums[i];} else {// 累加f[i] = nums[i] + f[i - 1];}// 检查此时是否达到最大值res = Math.max(res, f[i]);}return res;}
}

思路【我】:

空间优化版本。发现当前i只跟i-1的状态有关。用一个变量即可。

class Solution {public int maxSubArray(int[] nums) {int n = nums.length;int res = nums[0];int cur = nums[0];for (int i = 1; i < n; i++) {if (cur < 0) {cur = nums[i];} else {cur += nums[i];}res = Math.max(res, cur);}return res;}
}

另一种写法:

class Solution {public int maxSubArray(int[] nums) {// 注意不能有非空数组,且有负数,不能初始化成 0int res = nums[0];int f = 0;for (int x : nums) {f = Math.max(f, 0) + x;res = Math.max(res, f);}return res;}
}

2606. 找到最大开销的子字符串

思路【我】:

根据题意,chars和vals是制定了一些元素的值,其余字母还有默认值。所以,先新建数组myVals,先填默认值,再填指定值。

其余步骤和上题53. 最大子数组和是一样的。

最后返回的时候注意,如果res小于0,要考虑空串的情况,空串的开销是0,返回0。

class Solution {public int maximumCostSubstring(String s, String chars, int[] vals) {char[] chars2 = chars.toCharArray();int[] myVals = new int[128];// 先填默认值for (int i = 'a'; i <= 'z'; i++) {myVals[i] = i + 1 - 'a';}// 再填指定值for (int i = 0; i < chars2.length; i++) {myVals[chars2[i]] = vals[i];}// 53. 最大子数组和char[] ch = s.toCharArray();int n = ch.length;int cur = myVals[ch[0]];int res = cur;for (int i = 1; i < n; i++) {if (cur < 0) {cur = myVals[ch[i]];} else {cur += myVals[ch[i]];}res = Math.max(res, cur);}// 如果res小于0, 那就返回空串的开销(0)return res < 0 ? 0 : res;}
}

解决 res=0 的另一种写法:

char[] ch = s.toCharArray();
int n = ch.length;
int cur = 0;
// 允许空串,即允许子数组为空,所以res初始化为0
int res = 0;
// 要从0开始遍历
for (int i = 0; i < n; i++) {if (cur < 0) {cur = myVals[ch[i]];} else {cur += myVals[ch[i]];}res = Math.max(res, cur);
}
return res;

1749. 任意子数组和的绝对值的最大值

思路【我】:

总思路:正着来一遍,负着来一遍。

求最大的正的子数组和,最小的负的子数组和。

看他俩的绝对值谁更大

class Solution {public int maxAbsoluteSum(int[] nums) {// 总思路:正着来一遍,负着来一遍int n = nums.length;// 初始化int pos = nums[0];int neg = nums[0];int resP = nums[0];int resN = nums[0];// 从1开始从前往后for (int i = 1; i < n; i++) {// 最大的正的子数组和if (pos < 0) {pos = nums[i];} else {pos += nums[i];}resP = Math.max(resP, pos);// 最小的负的子数组和if (neg > 0) {neg = nums[i];} else {neg += nums[i];}resN = Math.min(resN, neg);}// 看他俩的绝对值谁更大return Math.max(resP, Math.abs(resN));}
}

思路:

使用更少变量的写法:

class Solution {public int maxAbsoluteSum(int[] nums) {// 因为可以允许为空,所以初始值可以赋值为0,然后遍历整个数组。int res = 0;int pos = 0;int neg = 0;for (int x : nums) {// 求最大子数组和pos = Math.max(pos, 0) + x;// 求最小子数组和neg = Math.min(neg, 0) + x;// 每一步都要更新res。看看是正的更正,还是负的更负res = Math.max(res, Math.max(pos, -neg));}return res;}
}
http://www.dtcms.com/a/358935.html

相关文章:

  • 微信小程序开发教程(三)
  • java如何保证线程安全
  • RLPD——利用离线数据实现高效的在线RL:不进行离线RL预训练,直接应用离策略方法SAC,在线学习时对称采样离线数据
  • 【OpenGL】LearnOpenGL学习笔记17 - Cubemap、Skybox、环境映射(反射、折射)
  • 【pandas】.loc常用操作
  • 【SpringMVC】SSM框架【二】——SpringMVC超详细
  • 【运维篇第三弹】《万字带图详解分库分表》从概念到Mycat中间件使用再到Mycat分片规则,详解分库分表,有使用案例
  • DAEDAL:动态调整生成长度,让大语言模型推理效率提升30%的新方法
  • 基于SpringBoot的电脑商城系统【2026最新】
  • 漫谈《数字图像处理》之分水岭分割
  • SystemVerilog学习【七】包(Package)详解
  • REST-assured获取响应数据详解
  • 数据结构 | 深度解析二叉树的基本原理
  • 访问Nginx 前端页面,接口报502 Bad Gateway
  • 【DeepSeek】ubuntu安装deepseek、docker、ragflow
  • 简历书写---自我评价怎么写
  • Day18_【机器学习—交叉验证与网格搜索】
  • Unity核心概念①
  • 【Linux】基础I/O和文件系统
  • PHP单独使用phinx使用数据库迁移
  • 全栈开源,高效赋能——启英泰伦新官网升级上线!
  • 快速学习和掌握Jackson 、Gson、Fastjson
  • React Native基本用法
  • 大语言模型生成的“超龄劳动者权益保障制度系统化完善建议(修订版)”
  • 下一波红利:用 #AI编程 闯入小游戏赛道,#看广告变现 模式正在崛起!
  • I2C的类比水池和大海
  • 【前端教程】DOM 操作入门专栏:从基础到实战
  • JS之刷刷
  • Langflow核心技术学习笔记(新)
  • LangChain.js 实战与原理:用 LCEL 构建可维护的 RAG / Agent 系统(含 4 套 30+ 行代码)