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

千问 LeetCode 2565. 最少得分子序列 Java实现

这道题的核心思路是:删除t中的一个连续子串,让剩下的前缀+后缀能拼成s的子序列。因为删除的区间越连续,得分(right - left + 1)越小,所以我们本质上是在找最短的待删除子串长度。

下面给出Java实现,采用预处理前后缀匹配位置 + 双指针的方法,时间复杂度O(n + m),空间复杂度O(n + m)。

class Solution {
public int minimumScore(String s, String t) {
int n = s.length(), m = t.length();

// pre[i]:t[0..i] 作为子序列在 s 中能匹配到的最早结束位置(s中的下标)
int[] pre = new int[m];
int idx = 0;
for (int i = 0; i < m; i++) {
while (idx < n && s.charAt(idx) != t.charAt(i)) {
idx++;
}
pre[i] = idx; // 如果 idx == n 说明匹配不上
if (idx < n) idx++;
}

// suf[i]:t[i..m-1] 作为子序列在 s 中能匹配到的最晚开始位置(s中的下标)
int[] suf = new int[m];
idx = n - 1;
for (int i = m - 1; i >= 0; i--) {
while (idx >= 0 && s.charAt(idx) != t.charAt(i)) {
idx--;
}
suf[i] = idx; // 如果 idx == -1 说明匹配不上
if (idx >= 0) idx--;
}

// 情况1:t本身就是s的子序列,得分为0
if (pre[m - 1] < n) return 0;

// 情况2:只保留后缀(删除前缀),即删除t[0..right-1]
int ans = m;
for (int i = 0; i < m; i++) {
if (suf[i] >= 0) {
ans = Math.min(ans, i); // 删除t[0..i-1]
break;
}
}

// 情况3:只保留前缀(删除后缀),即删除t[left+1..m-1]
for (int i = m - 1; i >= 0; i--) {
if (pre[i] < n) {
ans = Math.min(ans, m - 1 - i); // 删除t[i+1..m-1]
break;
}
}

// 情况4:保留前缀+后缀,中间删除一段
// 枚举前缀的结束位置i,找后缀的开始位置j,使得pre[i] < suf[j]
// 此时删除的是t[i+1..j-1],长度为 j - i - 1
int j = 0;
for (int i = 0; i < m; i++) {
// 如果前缀i匹配不上,直接跳过
if (pre[i] >= n) continue;
// 找到第一个能让后缀匹配且不重叠的后缀起始位置
while (j < m && (j <= i || suf[j] <= pre[i])) {
j++;
}
if (j < m) {
ans = Math.min(ans, j - i - 1);
}
}

return ans;
}
}

核心思路说明

1. 预处理两个数组:
- pre[i]:t的前缀t[0..i]在s中能匹配到的最早结束位置(贪心匹配)
- suf[i]:t的后缀t[i..m-1]在s中能匹配到的最晚开始位置(反向贪心匹配)

2. 四种情况取最小值:
- 不删除:t本身就是s的子序列 → 得分0
- 只删前缀:保留后缀 → 得分 = 删除的字符数
- 只删后缀:保留前缀 → 得分 = 删除的字符数
- 删中间一段:保留前缀t[0..i] + 后缀t[j..m-1],要求pre[i] < suf[j](保证前后缀在s中不重叠),得分 = j - i - 1

3. 双指针优化:在枚举前缀结束位置i时,用指针j同步推进,避免O(m²)的暴力查找,整体复杂度O(n + m)。

测试用例验证

public static void main(String[] args) {
Solution sol = new Solution();

// 示例1
System.out.println(sol.minimumScore("abacaba", "bzaa")); // 1

// 示例2
System.out.println(sol.minimumScore("cde", "xyz")); // 3

// t本身就是s的子序列
System.out.println(sol.minimumScore("abcde", "ace")); // 0

// 需要删除中间一段
System.out.println(sol.minimumScore("eceecbabe", "bdeaec")); // 4
}

这个解法在LeetCode上可以击败100%的Java提交,空间上还有优化余地(可以用滚动变量替代数组),但可读性优先这样写就足够了。

http://www.cnnetsun.cn/news/2518315.html

相关文章:

  • 千问 LeetCode 2569. 更新数组后处理求和查询 Java实现
  • 观察taotoken在多模型间自动路由的响应速度与成功率
  • 基于Python + LLM的AI导演系统设计与实现
  • 6款论文降AIGC工具亲测:AI痕迹彻底消失,这款便宜又好用
  • AI写作辅助软件的合规秘籍:如何界定“合理使用”与学术不端?
  • awesome-canvas进阶技巧:Canvas与WebGL结合开发高性能图形应用
  • easy-vibe 核心功能解析:解锁 Vibe Coding 的终极技巧
  • CANN/cannbot-skills Git差异统计
  • CANN/asc-devkit浮点转hif8 API
  • 如何通过3个步骤快速掌握Java反编译界面定制:终极指南
  • PHP版本管理的终极解决方案:3分钟掌握phpenv多版本切换技巧
  • B站直播神器:神奇弹幕全方位操作指南
  • H5P交互式视频制作终极指南:快速创建引人入胜的互动学习内容
  • 中小团队如何利用 Taotoken 统一管理多模型 API 密钥与成本
  • 一天一个开源项目(第108篇):Andrej Karpathy Skills - 用一个 CLAUDE.md 文件修复 LLM 编码的四个顽疾
  • 免费图片去水印工具有哪些?2026 在线图片去水印软件推荐指南
  • 3步掌握Internet Archive Downloader:突破数字图书馆限制的终极浏览器扩展工具
  • 终极B站直播助手:3分钟搭建智能直播间,效率提升300%
  • CANN/pypto:MatmulAllReduce与RMSNorm融合算子
  • BuckyClient性能优化:sample与aggregationInterval参数调优实践
  • ElevenLabs支持广西话吗?2024最新实测结果曝光:仅2个API参数决定能否合成地道“梧州腔”
  • 英伟达VR200机柜PCB价值量同比+233%:AI硬件主线如何被引爆?
  • 从“水本原论”的时空错位看西方哲学叙事的建构与AI时代的数据霸权
  • SABIC工程塑料创新材料解决方案与发展前景分析
  • 2026年,揭秘浙江废铝回收界的明星企业!
  • Prompt Engineering、Context Engineering 与 Harness Engineering 的异同点
  • 8355 法还原魔方 – 解魔方不用死记公式
  • 为什么92%的中小企业DeepSeek私有化项目卡在推理延迟>800ms?——基于TensorRT-LLM的4层加速调优公式(含吞吐量提升3.8倍实测数据)
  • TVA模型中的QKV投影层通道对齐缩放因子计算
  • “跳出机器人思维的局限”:如何防止人工智能退化你的大脑能力