Advertisement

Time to Cross a Bridge - LeetCode 2532 Solution

Time to Cross a Bridge - Complete Solution Guide

Time to Cross a Bridge is LeetCode problem 2532, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

There are k workers who want to move n boxes from the right (old) warehouse to the left (new) warehouse. You are given the two integers n and k , and a 2D integer array time of size k x 4 where time[i] = [right i , pick i , left i , put i ] . The warehouses are separated by a river and connected by a bridge. Initially, all k workers are waiting on the left side of the bridge. To move the boxes, the i th worker can do the following: Cross the bridge to the right side in right i minutes. Pick a bo

Detailed Explanation

The problem simulates a scenario where 'k' workers transport 'n' boxes from a right warehouse to a left warehouse across a bridge. Each worker has specific times for crossing the bridge to the right, picking up a box, crossing to the left, and putting down the box. Only one worker can cross the bridge at a time. Workers are prioritized based on their efficiency (or inefficiency, more accurately) – the less efficient worker crossing first, prioritizing the side that has completed the pick-up phase, before considering a worker on the left side. Efficiency is determined by the sum of their right and left crossing times; if these sums are equal, the worker with the higher index is considered less efficient. The goal is to find the time when the last box reaches the left side of the bridge.

Solution Approach

The solution employs a simulation approach. It uses four priority queues (heaps): `wait_left`, `wait_right`, `picking_right`, and `putting_left`. `wait_left` and `wait_right` store workers waiting on the left and right sides of the bridge, respectively, prioritized by inefficiency (largest left+right first). `picking_right` and `putting_left` store workers who are currently picking up boxes on the right and putting down boxes on the left, respectively, prioritized by completion time (smallest completion time first). The algorithm iterates until all boxes have crossed to the left side. In each iteration, it checks if any workers have finished picking up or putting down boxes and moves them to the appropriate waiting queues. Then, it prioritizes workers from `wait_right` to cross the bridge if available, otherwise from `wait_left` (if there are still boxes to dispatch). If both waiting queues are empty, it advances the time to the next event in either `picking_right` or `putting_left`.

Step-by-Step Algorithm

  1. Step 1: Initialize four priority queues: `wait_left`, `wait_right`, `picking_right`, and `putting_left`. Populate `wait_left` with the initial 'k' workers and their corresponding inefficiencies. In Python, the `wait_left` initialization utilizes the negative of the `left + right` values for proper max-heap behavior.
  2. Step 2: Initialize `current_time` to 0, `boxes_dispatched` to 0, and `boxes_crossed_to_left` to 0.
  3. Step 3: While `boxes_crossed_to_left` < 'n', repeat the following steps:
  4. Step 4: Move workers from `picking_right` to `wait_right` if their pickup completion time is less than or equal to `current_time`.
  5. Step 5: Move workers from `putting_left` to `wait_left` if their putdown completion time is less than or equal to `current_time`.
  6. Step 6: If `wait_right` is not empty, select the most inefficient worker (highest priority in max heap), move them to `putting_left` after crossing the bridge to the left, increment `boxes_crossed_to_left`, and update `current_time`.
  7. Step 7: Else, if `wait_left` is not empty and `boxes_dispatched` < 'n', select the most inefficient worker, move them to `picking_right` after crossing the bridge to the right, increment `boxes_dispatched`, and update `current_time`.
  8. Step 8: If both `wait_right` and `wait_left` are empty, advance `current_time` to the time of the next event (either a worker finishes picking up or putting down) if there are pending events. Break if there are no pending events.
  9. Step 9: Return `current_time`.

Key Insights

  • Insight 1: The core of the problem is managing the order of workers crossing the bridge based on their 'inefficiency' and availability on either side of the bridge. This requires maintaining multiple queues to track workers waiting on each side.
  • Insight 2: Prioritization is key. The problem specifies that the *least efficient* worker should be prioritized. A max-heap (priority queue) is suitable for this because it easily provides access to the element with the largest 'inefficiency' value.
  • Insight 3: The simulation requires tracking the completion times of workers who are currently picking up or putting down boxes. We use min-heaps for these tasks to efficiently determine when workers become available.
  • Insight 4: It's essential to consider edge cases where one side is empty, and the other side has workers available, or where all boxes have been dispatched from one side. We need to avoid sending unnecessary workers across the bridge if all the boxes are already on their way.
  • Insight 5: The question is asking the time when the LAST box reaches the left side, not when the last worker completes their action. Therefore, we should stop the simulation when all boxes reach the left side of the bridge.

Complexity Analysis

Time Complexity: O(n log k)

Space Complexity: O(k)

Topics

This problem involves: Array, Heap (Priority Queue), Simulation.

Companies

Asked at: LinkedIn.