山间拥堵小径通行时间计算:代码错误排查与优化求助
问题分析
你的代码错误核心在于仅处理了同一时间到达的徒步者批次,没有持续维护两个方向的队列并按时间线逐步处理后续到达的徒步者。在测试用例中,处理完第1个下山徒步者(时间0)后,第2个下山徒步者已经在时间1到达,此时应优先继续处理同方向的队列,而不是切换到上山队列。
正确实现思路
核心是模拟时间推进的全过程,维护两个方向的队列,并严格遵循优先级规则:
- 先将所有徒步者按到达时间+原始索引排序(保证到达时间相同时,索引小的先入队);
- 维护两个队列:
queue0(上山方向,0)、queue1(下山方向,1),存储徒步者的原始索引; - 跟踪当前时间
current_time和上一次通行的方向last_dir(初始为-1,表示无人通行); - 循环执行以下步骤直到所有队列空且所有徒步者处理完毕:
- 将所有到达时间≤
current_time的徒步者加入对应队列; - 根据优先级规则选择下一个通行的徒步者:
- 若双向队列都不为空:
- 初始状态(
last_dir=-1)→ 优先下山队列; - 上一次是下山(
last_dir=1)→ 继续优先下山队列; - 上一次是上山(
last_dir=0)→ 继续优先上山队列;
- 初始状态(
- 仅单方向队列非空→ 取该队列队首;
- 无队列非空→ 直接跳转到下一个徒步者的到达时间;
- 若双向队列都不为空:
- 记录该徒步者的通行时间为
current_time,更新current_time +=1和last_dir,并从队列中移除该徒步者。
- 将所有到达时间≤
Python 实现代码
def getResult(arrival, direction): n = len(arrival) # 打包成(到达时间, 原始索引, 方向),按到达时间+原始索引排序 hikers = sorted([(arrival[i], i, direction[i]) for i in range(n)], key=lambda x: (x[0], x[1])) queue0 = [] # 上山队列,存原始索引 queue1 = [] # 下山队列,存原始索引 res = [0] * n current_time = 0 last_dir = -1 # -1表示初始无通行 idx = 0 # 遍历sorted hikers的指针 while idx < n or queue0 or queue1: # 把所有到达时间<=current_time的徒步者加入对应队列 while idx < n and hikers[idx][0] <= current_time: arr_time, orig_idx, dir = hikers[idx] if dir == 0: queue0.append(orig_idx) else: queue1.append(orig_idx) idx += 1 # 选择下一个通行的徒步者 if queue0 and queue1: if last_dir == -1 or last_dir == 1: # 优先下山 selected = queue1.pop(0) last_dir = 1 else: # 上一次是上山,继续上山 selected = queue0.pop(0) last_dir = 0 elif queue0: selected = queue0.pop(0) last_dir = 0 elif queue1: selected = queue1.pop(0) last_dir = 1 else: # 无等待者,跳转到下一个徒步者的到达时间 current_time = hikers[idx][0] continue # 记录通行时间 res[selected] = current_time current_time += 1 return res # 测试用例 arrival = [0, 0, 1, 4] direction = [0, 1, 1, 0] print(getResult(arrival, direction)) # 输出 [2, 0, 1, 4]
Java 实现代码
import java.util.*; public class HikerPass { public static int[] getResult(int[] arrival, int[] direction) { int n = arrival.length; // 存储(到达时间, 原始索引, 方向),自定义排序规则 List<int[]> hikers = new ArrayList<>(); for (int i = 0; i < n; i++) { hikers.add(new int[]{arrival[i], i, direction[i]}); } // 按到达时间升序,到达时间相同则原始索引升序 Collections.sort(hikers, (a, b) -> { if (a[0] != b[0]) { return Integer.compare(a[0], b[0]); } else { return Integer.compare(a[1], b[1]); } }); Queue<Integer> queue0 = new LinkedList<>(); // 上山队列 Queue<Integer> queue1 = new LinkedList<>(); // 下山队列 int[] res = new int[n]; int currentTime = 0; int lastDir = -1; // -1表示初始无通行 int idx = 0; while (idx < n || !queue0.isEmpty() || !queue1.isEmpty()) { // 加入所有已到达的徒步者 while (idx < n && hikers.get(idx)[0] <= currentTime) { int[] hiker = hikers.get(idx); if (hiker[2] == 0) { queue0.add(hiker[1]); } else { queue1.add(hiker[1]); } idx++; } Integer selected = null; if (!queue0.isEmpty() && !queue1.isEmpty()) { if (lastDir == -1 || lastDir == 1) { selected = queue1.poll(); lastDir = 1; } else { selected = queue0.poll(); lastDir = 0; } } else if (!queue0.isEmpty()) { selected = queue0.poll(); lastDir = 0; } else if (!queue1.isEmpty()) { selected = queue1.poll(); lastDir = 1; } else { // 无等待者,跳转到下一个到达时间 currentTime = hikers.get(idx)[0]; continue; } res[selected] = currentTime; currentTime++; } return res; } public static void main(String[] args) { int[] arrival = {0, 0, 1, 4}; int[] direction = {0, 1, 1, 0}; int[] result = getResult(arrival, direction); System.out.println(Arrays.toString(result)); // 输出 [2, 0, 1, 4] } }
代码解释
- 排序处理:保证到达时间相同的徒步者按原始索引顺序入队,符合题目中
arrival[i]=arrival[j]且i<j则i先到达的规则; - 队列维护:持续将当前时间点已到达的徒步者加入对应队列,确保所有等待的徒步者都被纳入优先级判断;
- 优先级逻辑:严格遵循题目给出的三条规则,优先维持同方向通行,初始状态优先下山;
- 时间推进:当无等待者时,直接跳转到下一个徒步者的到达时间,避免无效的时间循环。
内容的提问来源于stack exchange,提问作者quantrader23
相关产品推荐
相关产品推荐

