Campus Bikes

medium greedy sorting manhattan distance

Problem

On a grid there are n workers and m bikes (n ≤ m), each at a point. We want to assign one unique bike to each worker. Repeatedly pick the (worker, bike) pair with the smallest Manhattan distance; ties break by smallest worker index, then smallest bike index. Once chosen, that worker and bike are removed. Return an array where answer[i] is the bike index assigned to worker i.

Inputworkers = [[0,0],[2,1]], bikes = [[1,2],[3,3]]
Output[0, 1]
Worker 0 to bike 0 (distance 3) and worker 1 to bike 0 (distance 2) both want bike 0; the closer pair (worker 1, bike 0) is taken first, leaving worker 0 with bike 1.

def assign_bikes(workers, bikes):
    pairs = []
    for i, (wx, wy) in enumerate(workers):
        for j, (bx, by) in enumerate(bikes):
            d = abs(wx - bx) + abs(wy - by)
            pairs.append((d, i, j))
    pairs.sort()
    ans = [-1] * len(workers)
    used_bike = [False] * len(bikes)
    for d, i, j in pairs:
        if ans[i] == -1 and not used_bike[j]:
            ans[i] = j
            used_bike[j] = True
    return ans
function assignBikes(workers, bikes) {
  const pairs = [];
  for (let i = 0; i < workers.length; i++)
    for (let j = 0; j < bikes.length; j++) {
      const d = Math.abs(workers[i][0] - bikes[j][0]) + Math.abs(workers[i][1] - bikes[j][1]);
      pairs.push([d, i, j]);
    }
  pairs.sort((a, b) => a[0] - b[0] || a[1] - b[1] || a[2] - b[2]);
  const ans = new Array(workers.length).fill(-1);
  const usedBike = new Array(bikes.length).fill(false);
  for (const [d, i, j] of pairs)
    if (ans[i] === -1 && !usedBike[j]) { ans[i] = j; usedBike[j] = true; }
  return ans;
}
int[] assignBikes(int[][] workers, int[][] bikes) {
    List<int[]> pairs = new ArrayList<>();
    for (int i = 0; i < workers.length; i++)
        for (int j = 0; j < bikes.length; j++) {
            int d = Math.abs(workers[i][0] - bikes[j][0]) + Math.abs(workers[i][1] - bikes[j][1]);
            pairs.add(new int[]{ d, i, j });
        }
    pairs.sort((a, b) -> a[0] != b[0] ? a[0] - b[0] : a[1] != b[1] ? a[1] - b[1] : a[2] - b[2]);
    int[] ans = new int[workers.length];
    Arrays.fill(ans, -1);
    boolean[] usedBike = new boolean[bikes.length];
    for (int[] p : pairs)
        if (ans[p[1]] == -1 && !usedBike[p[2]]) { ans[p[1]] = p[2]; usedBike[p[2]] = true; }
    return ans;
}
vector<int> assignBikes(vector<vector<int>>& workers, vector<vector<int>>& bikes) {
    vector<array<int,3>> pairs;
    for (int i = 0; i < (int)workers.size(); i++)
        for (int j = 0; j < (int)bikes.size(); j++) {
            int d = abs(workers[i][0] - bikes[j][0]) + abs(workers[i][1] - bikes[j][1]);
            pairs.push_back({ d, i, j });
        }
    sort(pairs.begin(), pairs.end());
    vector<int> ans(workers.size(), -1);
    vector<bool> usedBike(bikes.size(), false);
    for (auto& p : pairs)
        if (ans[p[1]] == -1 && !usedBike[p[2]]) { ans[p[1]] = p[2]; usedBike[p[2]] = true; }
    return ans;
}
Time: O(nm log(nm)) Space: O(nm)