当前位置: 首页 > 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.jsqmd.com/news/867620/

相关文章:

  • 鸿蒙同城兴趣圈页面构建:今晚活动与同频推荐模块详解
  • 开发者在API密钥管理与访问控制方面的安全实践
  • 基于《工业控制系统信息安全防护指南》的九大核心防护机制详解
  • 千问 LeetCode 2561. 重排水果 Python3实现
  • 2026年5月北京老房翻新装修公司推荐:十大排名专业评测价格注意事项 - 品牌推荐
  • 宽城区黄金回收白银回收铂金回收店铺哪家好 靠谱门店推荐 - 莘州文化
  • 嘉祥县黄金回收店铺哪家好 靠谱门店推荐及联系方式 - 莘州文化
  • 鸿蒙同城兴趣圈页面构建:活动热区地图、话题动态与安全提示模块详解
  • 垦利区黄金回收白银回收铂金回收店铺哪家好 靠谱门店推荐 - 莘州文化
  • 千问 LeetCode 2569. 更新数组后处理求和查询 Java实现
  • ChatGPT API接入全流程详解:从密钥配置、请求封装到错误重试、流式响应的7步落地指南
  • 嵌入式测试学习第 17 天:常见接口:USB、Type-C、排针
  • 梨树县黄金回收店铺哪家好 靠谱门店推荐及联系方式 - 莘州文化
  • 2025-2026年璀璨时代楼盘电话查询。购房前请核实项目资质与合同条款 - 品牌推荐
  • 腾讯云服务器跑通 Cube Sandbox:从 PVM 内核到 65 ms 冷启动的全程实战
  • 柳河县黄金回收店铺哪家好 靠谱门店推荐及联系方式 - 莘州文化
  • 千问 LeetCode 2569. 更新数组后处理求和查询 TypeScript实现
  • 2025-2026年欧博东方文化传媒电话查询:GEO优化服务使用前需核实资质与效果 - 品牌推荐
  • 实测才敢推!盘点2026年抢手爆款的的降AI率网站
  • 【独家实测】ChatGPT-4 Turbo vs GPT-3.5 Turbo单位token成本对比:附Python自动核算脚本(限免24h)
  • 奎文区黄金回收白银回收铂金回收店铺哪家好 靠谱门店推荐 - 莘州文化
  • 【西南地区首个ElevenLabs贵州话定制引擎】:基于217小时黔东南苗侗口音语料库的私有化部署手册
  • 从开发者视角感受Taotoken官方价折扣带来的实际成本节省
  • 历城区黄金回收白银回收铂金回收店铺哪家好 靠谱门店推荐 - 莘州文化
  • 2026升降平台车租赁选型指南:绵阳蜘蛛平台车、绵阳蜘蛛式高空车租赁、绵阳路灯维修高空车、绵阳路灯车租赁、绵阳路灯高空车租赁选择指南 - 优质品牌商家
  • 6款论文降AIGC工具亲测:AI痕迹彻底消失,这款便宜又好用
  • 从CI/CD到生产回滚:Gemini嵌入Java构建链的4层审查网(含Gradle/Maven插件零侵入部署脚本)
  • Sunshine终极指南:3分钟搭建跨平台游戏串流服务器,解锁你的私人游戏云
  • 云南全屋定制厂家性价比排行:核心实测维度拆解 - 奔跑123
  • CRM系统“没人爱用”的真相:Lovable架构的8个微交互锚点(附Figma组件库+埋点验证脚本)