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

DeepSeek LeetCode 3699. 锯齿形数组的总数 I Java实现

这道题的核心是动态规划 + 前缀和优化。因为数组的增减趋势必须交替(如 a<b>c<d),我们只需记录最后一个值和最后一步方向。

核心思路

· 状态定义:up[i] 表示最后一步为上升且以值 i 结尾的方案数;down[i] 同理为下降。
· 状态转移:
· 要形成新的上升(到 x),前一步必须是下降且结尾值 < x:newUp[x] = sum(down[0] + ... + down[x-1])。
· 要形成新的下降(到 x),前一步必须是上升且结尾值 > x:newDown[x] = sum(up[x+1] + ... + up[m-1])。
· 优化:用前缀和快速计算 newUp,用后缀和快速计算 newDown,避免遍历求和,将复杂度从 O(n·m²) 降至 O(n·m)。

---

Java 实现(空间优化版 O(m))

```java
class Solution {
private static final int MOD = 1_000_000_007;

public int zigZagArrays(int n, int l, int r) {
int m = r - l + 1; // 取值个数

// 初始化长度为 1 的情况:每个值都可以作为起点
long[] up = new long[m];
long[] down = new long[m];
for (int i = 0; i < m; i++) {
up[i] = 1;
down[i] = 1;
}

// 重复 n-1 次,每次在末尾添加一个数
for (int len = 2; len <= n; len++) {
long[] newUp = new long[m];
long[] newDown = new long[m];

// 计算前缀和(用于 newUp)
long prefixSum = 0;
for (int x = 0; x < m; x++) {
newUp[x] = prefixSum; // sum of down[0..x-1]
prefixSum = (prefixSum + down[x]) % MOD;
}

// 计算后缀和(用于 newDown)
long suffixSum = 0;
for (int x = m - 1; x >= 0; x--) {
newDown[x] = suffixSum; // sum of up[x+1..m-1]
suffixSum = (suffixSum + up[x]) % MOD;
}

up = newUp;
down = newDown;
}

// 答案:所有 up 和 down 之和
long ans = 0;
for (int i = 0; i < m; i++) {
ans = (ans + up[i] + down[i]) % MOD;
}
return (int) ans;
}
}
```

另一种写法(滚动数组 + 前缀和数组)

使用 prefixSums 和 suffixSums 辅助计算:

```java
class Solution {
private static final int MOD = 1_000_000_007;

public int zigZagArrays(int n, int l, int r) {
int m = r - l + 1;
int[] up = new int[m];
int[] down = new int[m];
int[] prefixUp = new int[m + 1];
int[] prefixDown = new int[m + 1];

for (int j = 0; j < m; j++) {
up[j] = 1;
down[j] = 1;
prefixUp[j + 1] = (prefixUp[j] + up[j]) % MOD;
prefixDown[j + 1] = (prefixDown[j] + down[j]) % MOD;
}

for (int i = 1; i < n; i++) {
int[] newUp = new int[m];
int[] newDown = new int[m];
int[] newPrefixUp = new int[m + 1];
int[] newPrefixDown = new int[m + 1];

for (int j = 0; j < m; j++) {
// 上升:前一步下降且值 < j
newUp[j] = (j > 0) ? prefixDown[j] : 0; // prefixDown[j] = sum(down[0..j-1])
// 下降:前一步上升且值 > j
newDown[j] = (j + 1 < m) ? (prefixUp[m] - prefixUp[j + 1] + MOD) % MOD : 0;

newPrefixUp[j + 1] = (newPrefixUp[j] + newUp[j]) % MOD;
newPrefixDown[j + 1] = (newPrefixDown[j] + newDown[j]) % MOD;
}

up = newUp;
down = newDown;
prefixUp = newPrefixUp;
prefixDown = newPrefixDown;
}

return (prefixUp[m] + prefixDown[m]) % MOD;
}
}
```

复杂度

· 时间复杂度:O(n·m)
· 空间复杂度:O(m)

http://www.jsqmd.com/news/1253920/

相关文章:

  • 瑶海区 7 店矩阵,易奢福全面覆盖!2026 合肥瑶海区易奢福腕表回收全程可视 - 易奢福
  • 深入解析MSPM0 UART:从寄存器配置到低功耗通信实战
  • 百考通:AI智能开题报告,让学术研究起步更高效智能化
  • 孩子背单词总忘别慌,这3款2026年最新实用软件亲测好用
  • 2026桂林黄金回收实测:6家正规门店推荐与避坑指南 - 观金堂黄金回收
  • WSL+Ubuntu22.04开发环境配置与优化指南
  • AI系统安全治理:自主智能体行为约束与防控机制
  • 2026黔西南卫生间渗水发霉最全解答!不砸砖防水靠谱吗?根治楼下渗水方法 - 宅安选房屋修缮
  • 深入解析TI DS92LV3241/3242 SerDes芯片:高速视频传输的硬件设计与调试实战
  • 英伟达全栈AI技术生态:从GPU芯片到应用部署的完整解析
  • DeepSeek开源模型在法证审计中的实践应用
  • 2026 嵩山少林小龙武术学校收费标准完整版,正规少林院校,暑期夏令营招生指南 - 全国文武学校招生
  • 2026 大连管道疏通口碑 TOP5 深度测评|正规疏通公司哪家好?资质_价格_上门速度全对比 - 米諾
  • 迪奥包包回收2026沧州须知 毓典寄卖行本地正规回收店铺 - 毓典寄卖行
  • Windows下YOLOv8环境搭建与优化指南
  • C#与Python跨语言整合:工业自动化中的YOLOv8模型部署
  • 连续性学习机制:从神经可塑性到动态知识图谱
  • 智能体技术演进与多智能体协同架构设计
  • Windows部署OpenClaw并与飞书集成实战指南
  • AI显微图像增强技术:原理、应用与优化
  • Qwen3-VL多模态AI架构解析与实战指南
  • MSP432E4硬件设计实战:GPIO驱动、时钟布线、以太网与USB接口设计精要
  • 兰州装修避坑干货!过来人真心话,少花几万冤枉钱 - 林州鸿途网络
  • 大模型技术学习路线:从Python基础到生产级开发
  • 北京公司资产重组律师实务指南:税务筹划与产权过户的流程把控 - 品牌深度评测
  • 河南 濮阳市2026 正规特训学校排名!8 大网瘾厌学叛逆专门教育机构,资质齐全支持实地考察 - Luckyone王
  • 2026年7月天津劳力士全国售后网络优化公告 新网点启用公示 - 亨得利全国维修中心38
  • API接口测试从入门到实战:Postman与Python自动化测试指南
  • DRA79x处理器DPI与GPMC接口时序配置与信号完整性实战
  • UE5高斯泼溅渲染实战:从原理到项目集成全流程解析