news 2026/5/22 3:27:19

千问 LeetCode 2532.过桥的时间 TypeScript实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
千问 LeetCode 2532.过桥的时间 TypeScript实现

下面给出 TypeScript 实现,思路与 Java 版本一致,使用四个优先队列模拟:

function findCrossingTime(n: number, k: number, time: number[][]): number {
// 1. 按效率排序:leftToRight + rightToLeft 越大效率越低,相同时下标越大效率越低
// 排序后下标即可代表效率优先级
time.sort((a, b) => (a[0] + a[2]) - (b[0] + b[2]));

// 等待过桥的工人:大顶堆,效率最低的优先
// 存储 [效率值, 下标]
const waitLeft: number[][] = [];
const waitRight: number[][] = [];

// 正在工作的工人:小顶堆,按完成时间排序
// 存储 [下标, 完成时间]
const workLeft: number[][] = [];
const workRight: number[][] = [];

// 堆操作辅助函数
const heapPush = (heap: number[][], item: number[], isMinHeap: boolean) => {
heap.push(item);
let i = heap.length - 1;
while (i > 0) {
const parent = Math.floor((i - 1) / 2);
const compare = isMinHeap
? heap[i][1] < heap[parent][1]
: heap[i][0] > heap[parent][0];
if (compare) {
[heap[i], heap[parent]] = [heap[parent], heap[i]];
i = parent;
} else break;
}
};

const heapPop = (heap: number[][], isMinHeap: boolean): number[] | undefined => {
if (heap.length === 0) return undefined;
const top = heap[0];
const last = heap.pop()!;
if (heap.length > 0) {
heap[0] = last;
let i = 0;
const n = heap.length;
while (true) {
let smallest = i;
const left = 2 * i + 1;
const right = 2 * i + 2;
if (left < n) {
const compare = isMinHeap
? heap[left][1] < heap[smallest][1]
: heap[left][0] > heap[smallest][0];
if (compare) smallest = left;
}
if (right < n) {
const compare = isMinHeap
? heap[right][1] < heap[smallest][1]
: heap[right][0] > heap[smallest][0];
if (compare) smallest = right;
}
if (smallest !== i) {
[heap[i], heap[smallest]] = [heap[smallest], heap[i]];
i = smallest;
} else break;
}
}
return top;
};

const heapPeek = (heap: number[][]): number[] | undefined => heap[0];

// 初始所有工人在左侧等待
for (let i = k - 1; i >= 0; i--) {
heapPush(waitLeft, [i, 0], false); // 大顶堆,按效率值(下标)比较
}

let curTime = 0;
let remain = n; // 剩余需要搬运的箱子数

while (remain > 0 || workRight.length > 0 || waitRight.length > 0) {
// 1. 将当前时间前完成工作的工人移到等待队列
while (workLeft.length > 0 && heapPeek(workLeft)![1] <= curTime) {
const [id] = heapPop(workLeft, true)!;
heapPush(waitLeft, [id, 0], false);
}
while (workRight.length > 0 && heapPeek(workRight)![1] <= curTime) {
const [id] = heapPop(workRight, true)!;
heapPush(waitRight, [id, 0], false);
}

// 2. 优先让右侧工人过桥
if (waitRight.length > 0) {
const [id] = heapPop(waitRight, false)!;
curTime += time[id][2]; // rightToLeft
heapPush(workLeft, [id, curTime + time[id][3]], true); // 到达左岸后放箱子
}
// 3. 否则,如果还有箱子要搬且左侧有人,派左侧工人过桥
else if (remain > 0 && waitLeft.length > 0) {
const [id] = heapPop(waitLeft, false)!;
curTime += time[id][0]; // leftToRight
heapPush(workRight, [id, curTime + time[id][1]], true); // 到达右岸后搬箱子
remain--;
}
// 4. 无人过桥,时间跳到下一个事件发生的时间
else {
let nextTime = Infinity;
if (workLeft.length > 0) nextTime = Math.min(nextTime, heapPeek(workLeft)![1]);
if (workRight.length > 0) nextTime = Math.min(nextTime, heapPeek(workRight)![1]);
curTime = nextTime;
}
}

// 收尾:所有箱子已搬完,让右侧所有工人依次过桥回到左岸
while (workRight.length > 0) {
const [id, finishTime] = heapPop(workRight, true)!;
curTime = Math.max(curTime, finishTime) + time[id][2];
}
while (waitRight.length > 0) {
const [id] = heapPop(waitRight, false)!;
curTime += time[id][2];
}

return curTime;
}

使用示例:

// 示例 1
console.log(findCrossingTime(1, 3, [[1,1,2,1],[1,1,3,1],[1,1,4,1]])); // 输出: 6

// 示例 2
console.log(findCrossingTime(3, 2, [[1,9,1,8],[10,10,10,10]])); // 输出: 50

关键说明:

1. 效率排序:先按 leftToRight + rightToLeft 升序排序,总和越大效率越低;相同时下标大的效率低。排序后下标即可代表效率优先级。
2. 四个堆:
- waitLeft / waitRight:大顶堆,按效率值(下标)比较,效率最低的优先过桥。
- workLeft / workRight:小顶堆,按完成时间比较,时间到了移到等待队列。
3. 模拟逻辑:每次循环先处理完成工作的工人,然后优先让右侧工人过桥,其次才是左侧工人(且需有剩余箱子)。无人过桥时跳到下一个事件时间。
4. 收尾处理:所有箱子搬完后,右侧可能还有工人没回来,需要让他们依次过桥回到左岸。

时间复杂度 O((n+k) log k),空间复杂度 O(k),可高效通过题目数据范围。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/22 3:16:40

Agent Runtime 重构:Session 作为事件日志的工程实践

1. 这不是新赛道&#xff0c;而是 runtime 层的“操作系统时刻”正在重演你有没有试过让一个 AI 代理连续工作四十分钟&#xff1f;不是闲聊&#xff0c;而是真干活&#xff1a;查数据库、调 API、读文档、写代码、改配置、再验证——一环扣一环。去年我带团队跑一个客户的数据…

作者头像 李华
网站建设 2026/5/22 3:15:34

Generative Ops:业务系统自优化的轻量级落地实践

1. 项目概述&#xff1a;这不是又一个AI概念炒作&#xff0c;而是一套可落地的业务自优化操作系统“Generative Ops”这个词刚出来时&#xff0c;我第一反应是皱眉——又一个把生成式AI和运维&#xff08;Ops&#xff09;硬凑在一起的营销造词。但真正花三周时间拆解了十家已上…

作者头像 李华
网站建设 2026/5/22 3:13:40

现代 C++ 助力 GOLDE:康威生命游戏模拟无限的技术突破!

1. 项目背景发布于 2026 年 5 月 14 日&#xff0c;更新于 2026 年 5 月 16 日&#xff0c;作者使用现代 C 在康威生命游戏中模拟无限。[GOLDE] 是一款用于细胞自动机的编辑器和模拟器&#xff0c;能够瞬间模拟数万亿代。八个月前&#xff0c;作者在没有任何 C 经验的情况下开始…

作者头像 李华
网站建设 2026/5/22 3:12:50

scikit-learn自定义Pipeline:从接口契约到业务落地的完整实践

1. 项目概述&#xff1a;为什么需要自己动手定制 scikit-learn 的模型与流水线在真实的数据科学项目里&#xff0c;你几乎不可能靠from sklearn.ensemble import RandomForestClassifier一行代码就搞定所有事。我带过十几个工业级建模项目&#xff0c;从电商价格预测到医疗设备…

作者头像 李华
网站建设 2026/5/22 3:11:11

LSTM门控机制原理解析:从时间序列建模电路设计到工业落地

1. 这不是“又一个LSTM教程”&#xff1a;它到底在解决什么真实问题&#xff1f;你打开TensorFlow文档&#xff0c;看到tf.keras.layers.LSTM那一行&#xff0c;参数列表密密麻麻&#xff1a;units、return_sequences、dropout、recurrent_dropout……点开Stack Overflow&#…

作者头像 李华
网站建设 2026/5/22 3:04:52

如何3步完成Windows和Office永久激活:KMS_VL_ALL_AIO终极指南

如何3步完成Windows和Office永久激活&#xff1a;KMS_VL_ALL_AIO终极指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO KMS_VL_ALL_AIO是一款功能强大的智能激活脚本工具&#xff0c;专为Wind…

作者头像 李华