Start learning free

LESSON 457 OF 671 · HEAP

Minimum Number of Boats - Time Complexity: O(n log n) - JavaScript

Practice O(n log n) Read the full explanation

You get an array weights. Each number is the weight of one student. You also get two limits, maxWeight and maxDiff.

All the students must cross a river by boat. There are as many boats as needed. Return the smallest number of boats that takes everyone across.

A boat carries one student or two. Two students can share a boat only if their weights add up to at most maxWeight. Their weights must also differ by at most maxDiff.

 

Example 1:

Input: weights = [3, 5, 4, 6], maxWeight = 9, maxDiff = 1
Output: 3
Explanation: One way is (3, 4), (5) and (6).
5 and 6 can't share a boat.
Together they weigh 11, more than 9.

Example 2:

Input: weights = [2, 9, 1, 8], maxWeight = 10, maxDiff = 3
Output: 3
Explanation: The boats are (1, 2), (8) and (9).
(1, 9) and (2, 8) are light enough.
But their weights differ by more than 3.

Example 3:

Input: weights = [12, 5, 4], maxWeight = 10, maxDiff = 2
Output: 2
Explanation: 4 and 5 share a boat.
The student who weighs 12 rides alone.

 

Constraints:

  • 1 to 30,000 students.
  • Each weight is from 0 to 100,000,000.
  • maxWeight is from 1 to 100,000.
  • maxDiff is from 1 to 10,000.
  • A student may weigh more than maxWeight. That student rides alone.
STEP 1 OF 15
    Ctrl + Enter to check

    JAVASCRIPT · HEAP

    Minimum Number Of Boats in JavaScript, explained

    Understanding the Problem

    The core challenge of this problem is to minimize the number of boats required to transport all students while adhering to the constraints of maximum weight and weight difference. This problem is significant in scenarios like evacuation planning, resource allocation, and logistics where optimizing the number of trips or resources is crucial.

    Potential pitfalls include not considering the weight difference constraint or not pairing students optimally, leading to an increased number of boats.

    Approach

    To solve this problem, we need to think about pairing students in a way that maximizes the utilization of each boat. A naive solution would be to try every possible pair, but this would be computationally expensive. Instead, we can use a more efficient approach:

    1. Sort the array of weights.
    2. Use a two-pointer technique to try and pair the lightest and heaviest students that can share a boat.
    3. If they can share a boat, move both pointers inward; otherwise, move only the pointer for the heavier student.

    This approach ensures that we are always trying to pair the heaviest possible student with the lightest possible student, which helps in minimizing the number of boats.

    Algorithm

    Here is a step-by-step breakdown of the algorithm:

    1. Sort the array of weights.
    2. Initialize two pointers: one at the start (lightest) and one at the end (heaviest) of the sorted array.
    3. Initialize a counter for the number of boats.
    4. While the start pointer is less than or equal to the end pointer:
      • Check if the current pair of students can share a boat based on the weight and weight difference constraints.
      • If they can share a boat, increment the start pointer and decrement the end pointer.
      • If they cannot share a boat, decrement only the end pointer.
      • Increment the boat counter in each iteration.
    5. Return the boat counter as the result.

    Code Implementation

    /**
     * @param {number[]} weights
     * @param {number} maxWeight
     * @param {number} maxDiff
     * @return {number}
     */
    function minNumberOfBoats(weights, maxWeight, maxDiff) {
        // Sort the weights array
        weights.sort((a, b) => a - b);
        
        let start = 0;
        let end = weights.length - 1;
        let boats = 0;
        
        while (start <= end) {
            // Check if the lightest and heaviest can share a boat
            if (weights[start] + weights[end] <= maxWeight && Math.abs(weights[start] - weights[end]) <= maxDiff) {
                start++;
                end--;
            } else {
                end--;
            }
            boats++;
        }
        
        return boats;
    }
    
    // Example usage:
    console.log(minNumberOfBoats([2, 4, 2, 1], 6, 1)); // Output: 3
    console.log(minNumberOfBoats([81, 37, 32, 88, 55, 93, 45, 72], 100, 10)); // Output: 6
    

    Complexity Analysis

    The time complexity of this approach is O(n log n) due to the sorting step. The two-pointer traversal is O(n), making the overall complexity O(n log n). The space complexity is O(1) as we are using a constant amount of extra space.

    Edge Cases

    Potential edge cases include:

    • All students have the same weight.
    • Only one student.
    • Weights that exactly match the maxWeight and maxDiff constraints.

    These cases are handled by the algorithm as it systematically checks each pair of students.

    Testing

    To test the solution comprehensively, consider the following test cases:

    • Simple cases with a few students.
    • Cases where no two students can share a boat.
    • Cases with large arrays to test performance.

    Using a testing framework like Jest can help automate and validate these test cases.

    Thinking and Problem-Solving Tips

    When approaching such problems, consider the following tips:

    • Break down the problem into smaller, manageable parts.
    • Think about edge cases and constraints early on.
    • Use sorting and two-pointer techniques for optimization.
    • Practice similar problems to improve problem-solving skills.

    Conclusion

    In this blog post, we discussed how to solve the problem of minimizing the number of boats required to transport students given weight and weight difference constraints. We explored a two-pointer approach that optimizes the solution and provided a detailed explanation and code implementation. Understanding and solving such problems is crucial for developing efficient algorithms and improving problem-solving skills.

    Additional Resources

    For further reading and practice, consider the following resources:

    Keep going with JavaScript650+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free