Skip to content

Latest commit

 

History

History
138 lines (112 loc) · 3.55 KB

1057-campus-bikes.md

File metadata and controls

138 lines (112 loc) · 3.55 KB

Here is my video explaining it: https://youtu.be/tAMRNMh_VCU

/**
 * @param {number[][]} workers
 * @param {number[][]} bikes
 * @return {number[]}
 */

const getDistance = (worker, bike) => {
    return Math.abs(worker[0] - bike[0]) + Math.abs(worker[1] - bike[1])
}

// O(NM*log(NM))
// O(NM)
// var assignBikes = function(workers, bikes) {
//     // n ^ 2
//     // [i, j , distance] => O(n ^ 2)
//     //  sort => distance, worker index(if bike is the same),, bike index (if worker is the same) 
//     // [0, 0, 1]
//     // [1, 0, 1]
//     // [1, 2, 1]
//     // [2, 0, 1]
//     // [2, 2, 1]
//     // ....
    
    
//     //1. get all combinations
//     // O(N * M) both for Time/Space
//     const combinations = []
//     for (let i = 0; i < workers.length; i++) {
//         for (let j = 0; j < bikes.length; j++) {
//             combinations.push([i, j, getDistance(workers[i], bikes[j])])
//         }
//     }
    
//     // 2. sort them, distance > worker => bike
//     // O(N * M * log(N * M))
//     combinations.sort((a, b) => {
//         if (a[2] === b[2]) {
//             if (a[0] === b[0]) {
//                 return a[1] - b[1]
//             } else {
//                 return a[0] - b[0]
//             }
//         } else {
//             return a[2] - b[2]
//         }
//     })
    
//     // 3. collect result
//     const result = []
//     // O(N) + O(M)
//     // O(NM)
//     const usedWorker = new Set()
//     const usedBike = new Set()
//     for (let combination of combinations) {
//         const [workerIndex, bikeIndex] = combination
//         if (!usedWorker.has(workerIndex) && !usedBike.has(bikeIndex)) {
//             result[workerIndex] = bikeIndex
//             usedWorker.add(workerIndex)
//             usedBike.add(bikeIndex)
//         }
        
//         if (usedWorker.size === workers.length) {
//             break
//         }
//     }
    
//     return result
// };



// Time: O(Max(workers[i][0], bikes[i][0]) * Max(workers[i][1], bikes[i][1]))
// Space: O(NM)
var assignBikes = function(workers, bikes) {
    //1. get all combinations
    // Time: O(NM)
    // Space: O(NM)  depends on the implement of sparse array.
    const combinations = []
    for (let i = 0; i < workers.length; i++) {
        for (let j = 0; j < bikes.length; j++) {
            const distance = getDistance(workers[i], bikes[j])
            if (!combinations[distance]) {
                combinations[distance] = []
            }
            combinations[distance].push([i, j])
        }
    }
    
    // notice now combinations might be a sparse array
    // 2. collect result
    const result = []
    
    
    const Used = {
        _usedWorker: new Set(),
        _usedBike: new Set(),
        has(i, j) {
            return this._usedWorker.has(i) || this._usedBike.has(j)
        },
        set(i, j) {
            this._usedWorker.add(i)
            this._usedBike.add(j)
        }
    }
    
    // Space: O(N) + O(M)
    const usedWorker = new Set()
    const usedBike = new Set()
    // Time: worst would be O(Max(workers[i][0], bikes[i][0]) * Max(workers[i][1], bikes[i][1]))
    for (let combination of combinations) {
        if (!combination) continue
        // Time: Totally O(NM)
        for (let [workerIndex, bikeIndex] of combination) {
            if (!Used.has(workerIndex, bikeIndex)) {
                result[workerIndex] = bikeIndex
                Used.set(workerIndex, bikeIndex)
            }
            
            if (usedWorker.size === workers.length) {
                break
            }
        }
    }
    
    return result
};