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

千问 LeetCode 3911. 移除子数组元素后第 K 小偶数 Java实现

这道题的核心是二分查找 + 序号映射:把偶数映射为序号,问题转化为"从自然数序列中删除若干序号后找第 k 个剩余序号",再用二分定位答案。

题目理解

给定严格递增数组 nums 和查询 [l, r, k]:从全局正偶数序列 (2, 4, 6, 8, ...) 中,移除 nums[l..r] 子数组里出现的所有偶数,返回剩下的第 k 个偶数。

核心思路

1. 序号映射:偶数 v 对应序号 v/2(从 1 开始),全局偶数序列就是序号序列 1, 2, 3, ...,答案 = 2 × 第k个剩余序号
2. 预处理:遍历 nums,把所有偶数的原始下标存入 evenPos(因 nums 严格递增,下标天然有序)
3. 每个查询:
- 在 evenPos 中二分找到子数组 [l, r] 内的偶数下标区间 [left, right)
- 这些偶数对应的序号构成严格递增的"被删除集合" S
- 问题转化为:从自然数序列中删掉 S,找第 k 个剩余序号
4. 找第 k 个剩余序号:用二分或数学方法,跳过被删除的序号定位答案

Java 实现

class Solution {
public int[] kthRemainingInteger(int[] nums, int[][] queries) {
int n = nums.length;

// 预处理:收集所有偶数元素的原始下标
List<Integer> evenPos = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (nums[i] % 2 == 0) {
evenPos.add(i);
}
}

int[] ans = new int[queries.length];

for (int q = 0; q < queries.length; q++) {
int l = queries[q][0], r = queries[q][1], k = queries[q][2];

// 二分找到 evenPos 中第一个 >= l 的位置
int left = lowerBound(evenPos, l);
// 二分找到 evenPos 中第一个 > r 的位置
int right = upperBound(evenPos, r);

// evenPos[left..right) 就是子数组 [l,r] 内所有偶数的下标
// 对应的偶数值为 nums[evenPos[i]],序号为 nums[evenPos[i]] / 2
// 从全局偶数序列中删掉这些序号后,找第 k 个剩余序号

long result = findKthRemaining(evenPos, nums, left, right, k);
ans[q] = (int) result;
}

return ans;
}

/**
* 在被删除的偶数序号集合中,找第 k 个剩余序号,返回对应的偶数值
*/
private long findKthRemaining(List<Integer> evenPos, int[] nums,
int left, int right, long k) {
// 被删除的序号个数
int removedCount = right - left;

if (removedCount == 0) {
// 没有偶数被删除,直接返回第 k 个偶数
return 2L * k;
}

// 被删除的序号集合:nums[evenPos[i]] / 2,i in [left, right)
// 这些序号严格递增
// 用二分:在值域上找第 k 个不在被删除集合中的序号

long lo = 1, hi = 2L * (k + removedCount); // 上界足够大
long ans = hi;

while (lo <= hi) {
long mid = lo + (hi - lo) / 2;
// 计算 [1, mid] 中有多少个被删除的序号
long removedInRange = countRemovedInRange(evenPos, nums, left, right, mid);
// [1, mid] 中剩余的序号个数
long remaining = mid - removedInRange;

if (remaining >= k) {
ans = mid;
hi = mid - 1;
} else {
lo = mid + 1;
}
}

return 2L * ans;
}

/**
* 计算被删除序号集合中,值 <= target 的个数
*/
private long countRemovedInRange(List<Integer> evenPos, int[] nums,
int left, int right, long target) {
// 在被删除的偶数中,找值 <= 2*target 的个数
// 即 nums[evenPos[i]] <= 2*target
long val = 2L * target;
int lo = left, hi = right - 1;
int pos = left - 1;

while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (nums[evenPos.get(mid)] <= val) {
pos = mid;
lo = mid + 1;
} else {
hi = mid - 1;
}
}

return pos - left + 1;
}

private int lowerBound(List<Integer> list, int target) {
int lo = 0, hi = list.size();
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (list.get(mid) >= target) hi = mid;
else lo = mid + 1;
}
return lo;
}

private int upperBound(List<Integer> list, int target) {
int lo = 0, hi = list.size();
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (list.get(mid) > target) hi = mid;
else lo = mid + 1;
}
return lo;
}
}

关键点解析

- 序号映射:偶数 v → 序号 v/2,把"偶数序列删除"问题转化为"自然数序列删除"问题,简化思考
- 二分定位子数组偶数:lowerBound(l) 和 upperBound(r) 快速找到 [l,r] 内偶数的下标区间,避免线性扫描
- 值域二分找答案:在序号值域上二分,对每个候选值 mid,统计 [1, mid] 中被删除的序号个数,从而算出剩余序号个数,与 k 比较调整边界
- 时间复杂度:预处理 O(n),每个查询 O(log²M)(M 为值域大小),整体高效

需要我帮你整理一份"二分查找"的通用模板吗?包括 lower_bound、upper_bound 的各种变体,方便你直接套用。

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

相关文章:

  • 如何免费精准计算 AI Token 数量:一份 Tiktokenizer 完全指南
  • 从“守护者”到“驱动者”——犬肠成纤维细胞在肠道纤维化病理机制与药物评价中的核心价值
  • 5分钟做出第一个自动化脚本:Pulover‘s Macro Creator零基础入门全攻略
  • AI探索人类意识:从情感计算到存在论对话
  • 思源宋体CN免费商用指南:七种字重的中文宋体,从安装到项目落地一次讲透
  • C-Lodop Web打印控件部署与错误排查实战指南
  • C# JSON处理:Newtonsoft.Json高级特性与性能优化实战
  • 从“兴趣”到“职业”:Python学习全阶段规划,新手必看
  • 即推GEO媒体投放功能:权威媒体信源补强,进阶拉升GEO优化权重
  • 谢飞机大闹大厂面试:从音视频缓存到微服务熔断的JVM奇遇记
  • Linux系统时间修改:date与hwclock命令详解与实战避坑指南
  • Bochs虚拟机实战指南:从仿真原理到操作系统开发调试
  • Figma 界面汉化一次搞定:FigmaCN 插件完整上手指南
  • 知识蒸馏技术详解:从核心原理到工程实践,实现模型高效压缩与部署
  • 企业级知识图谱构建:基于本体论的统一语义层设计与AI集成实践
  • 产品经理不再画原型了——用myBuilder直接搭出开发能用的界面
  • AI视频创作新思路:Seedance 2.5与PixVerse整合工作流实战解析
  • Claude Opus 5实测:半价之下,代码、对话与创意能力全面解析
  • ChatGPT、Codex实战:Linux桌面版怎么用?装好了还不好用,真正要检查的是这6个地方
  • IDEA中Git Pull与Update Project核心区别与最佳实践指南
  • FreeRTOS(创建任务)
  • GValue:构建统一价值度量体系,解决多目标业务决策难题
  • 3 分钟上手的抖音下载工具:一个链接,通吃视频、图集、原声和整个作者主页
  • Oracle 19c静默安装全攻略:从系统配置到自动化部署
  • 新建胶合板生产线如何选烘干设备|邢台巨工机械单板烘干机(板皮烘干机)人造板设备厂家推荐 - 米諾
  • 上海钻戒回收六大骗局全拆解:从“虚高引流”到“调包压级”,2026合规门店交易避坑手册 - 一刻涨新知
  • 任务栏透明全配置指南:用 settings.json 玩转 TranslucentTB 动态模式
  • 绝区零一条龙完整上手指南:自动战斗与每日任务的一键托管玩法
  • Qt Creator悬浮注释配置指南:提升C++开发效率的关键技巧
  • vue fastapi admin 使用