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

DeepSeek LeetCode 3777. 使子字符串变交替的最少删除次数 Java实现

这道题是 LeetCode 3777,题名为「使子字符串变交替的最少删除次数」(Minimum Deletions to Make Alternating Substring)。这是一道困难题,需要同时处理动态修改和区间查询。

📝 题目描述

· 输入:一个长度为 n 的字符串 s(仅含 'A'/'B'),和 q 个查询 queries。
· 操作类型:
· [1, j]:翻转 s[j](A变B,B变A)。
· [2, l, r]:查询将子串 s[l..r] 变为交替字符串(相邻字符不同)所需的最少删除次数。
· 输出:按顺序返回所有 [2, l, r] 查询的结果数组。

💡 核心解法:线段树 (Segment Tree)

由于有高达 10^5 的单点更新和区间查询,需要一种能同时高效处理这两种操作的数据结构——线段树。

核心思路:对于任何区间,其最小删除次数可以分治合并。用线段树维护每个区间三个信息:

1. 左端点字符 (lc)
2. 右端点字符 (rc)
3. 最小删除次数 (del_cnt)

合并方法:合并左右子区间时,总删除次数 = 左区间删除次数 + 右区间删除次数 + (左区间右端点 == 右区间左端点 ? 1 : 0)。

💻 参考代码 (Java)

```java
class Solution {
// 线段树节点
static class Data {
char lc, rc; // 区间左右端点字符
int del; // 变成交替串的最小删除次数
Data(char lc, char rc, int del) { this.lc = lc; this.rc = rc; this.del = del; }
}

private Data[] tree;
private char[] chars;

public int[] minDeletions(String s, int[][] queries) {
int n = s.length();
this.chars = s.toCharArray();
// 线段树数组大小开4倍n
this.tree = new Data[4 * n];
build(1, 0, n - 1);

List<Integer> ansList = new ArrayList<>();
for (int[] q : queries) {
if (q[0] == 1) { // 更新操作
update(1, 0, n - 1, q[1]);
} else { // 查询操作
Data res = query(1, 0, n - 1, q[1], q[2]);
ansList.add(res.del);
}
}
return ansList.stream().mapToInt(i -> i).toArray();
}

// 合并两个节点信息
private Data merge(Data left, Data right) {
if (left == null) return right;
if (right == null) return left;
// 核心逻辑:左右相邻字符相同,则需多删一个
int add = (left.rc == right.lc) ? 1 : 0;
return new Data(left.lc, right.rc, left.del + right.del + add);
}

// 构建线段树
private void build(int node, int l, int r) {
if (l == r) {
tree[node] = new Data(chars[l], chars[l], 0);
return;
}
int mid = (l + r) / 2;
build(node * 2, l, mid);
build(node * 2 + 1, mid + 1, r);
tree[node] = merge(tree[node * 2], tree[node * 2 + 1]);
}

// 单点更新(翻转字符)
private void update(int node, int l, int r, int idx) {
if (l == r) {
// 翻转字符:'A' <-> 'B'
chars[l] = (chars[l] == 'A') ? 'B' : 'A';
tree[node] = new Data(chars[l], chars[l], 0);
return;
}
int mid = (l + r) / 2;
if (idx <= mid) update(node * 2, l, mid, idx);
else update(node * 2 + 1, mid + 1, r, idx);
tree[node] = merge(tree[node * 2], tree[node * 2 + 1]);
}

// 区间查询
private Data query(int node, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) return tree[node];
int mid = (l + r) / 2;
if (qr <= mid) return query(node * 2, l, mid, ql, qr);
if (ql > mid) return query(node * 2 + 1, mid + 1, r, ql, qr);
// 查询区间跨越左右子树,需要合并结果
Data leftRes = query(node * 2, l, mid, ql, qr);
Data rightRes = query(node * 2 + 1, mid + 1, r, ql, qr);
return merge(leftRes, rightRes);
}
}
```

⏱️ 复杂度分析

· 时间复杂度:
· 构建树:O(n)
· 每次更新或查询:O(log n)
· 总体:O((n + q) * log n)
· 空间复杂度:O(n),主要是线段树数组开销。

理解“左右端点字符 + 删除次数”这个合并逻辑是关键。如果还有不清楚的地方,随时可以再问我。

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

相关文章:

  • 智创共赢|暴雨装备解码产业实践‌
  • 3D打印智能灯光系统DIY:从Arduino编程到光影艺术
  • 图形化编程入门:用Mind+画图掌握编程核心概念
  • FanControl终极指南:3分钟打造静音高效的Windows风扇控制系统
  • 先把 Agent 做好,再谈 AGI
  • 2026年7月短视频广告投流服务商推荐,无锡市有实力的短视频广告投流口碑推荐 - 品牌推荐师
  • 无人机地面站起飞条件检测系统:基于状态机与规则引擎的PyQt5实现
  • OpenClaw框架:System Prompt优化与Context Compression技术详解
  • 终极植物大战僵尸PC版修改器:完整使用指南与创新玩法
  • 2026环境好的雷霆战机线下服务门店精选推荐
  • 物联网设备射频PCB布局与天线设计实战指南:基于TI CC3220MODx模块
  • 词云AI·系统大更新!二级代理、线路管控、通话性能全面升级|产品更新
  • 武汉中职/中专想读日语专业选什么学校好? - 升学择校早知道
  • 2026下半年天津滨海新区继承纠纷横向测评,深度调研三个月回应房产继承分割 - 资讯快报
  • 绝地求生罗技鼠标宏完整指南:如何配置压枪脚本快速提升射击精度
  • FAST-LIO中IMU误差模型与噪声参数调优
  • DeepSeek LeetCode 3777. 使子字符串变交替的最少删除次数 Python3实现
  • NS-USBloader:一站式解决Switch游戏安装难题的跨平台工具
  • 基于CC2538与Z-Stack的智能电表设计:从硬件选型到ZigBee协议栈集成
  • LTE Cat 1bis模块与ARM Cortex-M4F的物联网通信方案
  • OpenClaw模块化AI框架解析与应用实践
  • Intel Edison开发板环境搭建、编程与硬件通信实战指南
  • |放弃高考独木桥,走通公办捷径|成都竞元单招2026集训全景解读 - 成都竞元单招
  • 一张衣服照片几百万个像素,AI到底在看什么?
  • Go语言高并发消息发送:WorkerPool模式实战
  • 上海水洗石路面施工企业推荐,认准隆升(上海)园林绿化工程 - 资讯纵览
  • 2026年沈阳门窗/辽宁系统门窗/断桥铝门窗厂家推荐榜单:保温隔音、节能别墅门窗与阳光房天井深度测评 - 优企名品
  • 9大网盘直链下载助手:告别限速烦恼,获取真实下载地址
  • 3步掌握TMSpeech:彻底解决离线语音转文字隐私问题的终极方案
  • 上班族塑料饭盒避坑指南 台州源头工厂推荐 - 资讯纵览