Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1359. Count All Valid Pickup and Delivery Options - Leetcode Solution

Problem Description

You are given an integer n, representing the number of orders. Each order consists of a pickup and a delivery task, denoted as P_i and D_i for the i-th order.

Your task is to count all valid sequences of pickup and delivery tasks such that for every order i, pickup P_i occurs before delivery D_i in the sequence.

The answer can be very large, so return it modulo 10^9 + 7.

  • Each pickup and delivery must be used exactly once.
  • Pickups and deliveries cannot be reused or swapped between orders.
  • There is only one valid answer for each input n.

Thought Process

At first glance, you might consider generating all possible permutations of the 2n events (pickups and deliveries) and then filtering out the invalid ones where a delivery comes before its pickup. However, this brute-force approach quickly becomes infeasible as n increases, because the number of permutations grows factorially.

Instead, we look for a pattern or formula to count the valid arrangements directly. We realize that for each order, the delivery must always come after its pickup, and the relative order between different pickups and deliveries can vary, as long as this rule is followed for every pair.

This leads us to consider a recursive or combinatorial approach, where we build up the solution by adding one order at a time and counting how many ways the new pickup and delivery can be inserted into the existing sequence.

Solution Approach

The key insight is to build the sequence order by order, considering how to insert the new pickup and delivery into the existing valid sequence.

  • For n orders, there are 2n slots in the sequence.
  • When adding the n-th order, we must insert its pickup and delivery into the sequence such that the pickup comes before the delivery.
  • If we have a valid sequence for n-1 orders, there are 2n-1 possible positions to insert the new pickup. After inserting the pickup, there are 2n-1 positions left, but only those after the pickup are valid for the delivery (to maintain the pickup-before-delivery rule).
  • For each possible position of the pickup, the delivery can be inserted in any slot after it. This gives 2n-1 choices for the pickup and, for each, 2n-2 choices for the delivery (since we can't put delivery before pickup).
  • But instead of choosing positions, we can directly use the formula: For each new order, the number of ways to insert its pickup and delivery is i * (2i - 1), where i is the current order number.
  • Therefore, the total number of valid sequences is the product of i * (2i - 1) for all i from 1 to n.

Algorithm Steps:

  1. Initialize result as 1.
  2. For i from 1 to n:
    • Multiply result by i (ways to insert pickup).
    • Multiply result by 2i - 1 (ways to insert delivery after pickup).
    • Take modulo 10^9 + 7 at each step to avoid overflow.
  3. Return result at the end.

Example Walkthrough

Let's walk through the process for n = 3:

  • Start with result = 1
  • For i = 1: result = result * 1 * (2*1-1) = 1 * 1 * 1 = 1
  • For i = 2: result = result * 2 * (2*2-1) = 1 * 2 * 3 = 6
  • For i = 3: result = result * 3 * (2*3-1) = 6 * 3 * 5 = 90

So, for n = 3, there are 90 valid sequences.

This matches the expected output and demonstrates how the formula quickly computes the answer without generating all permutations.

Time and Space Complexity

Brute-force approach: Generating all permutations of 2n events and filtering them would take O((2n)!) time and space, which is impractical even for small n.

Optimized approach: Our approach only iterates from 1 to n, performing constant-time operations in each step.

  • Time Complexity: O(n) (one loop through n).
  • Space Complexity: O(1) (only a few integer variables used).

Summary

The problem challenges us to count valid pickup and delivery sequences for n orders, ensuring each pickup precedes its delivery. While a brute-force solution is infeasible, the combinatorial insight leads to a simple and efficient product formula: for each order, multiply by the number of ways to insert its pickup and delivery. This results in a fast O(n) solution that elegantly solves the problem using basic arithmetic and modular operations.

Code Implementation

class Solution:
    def countOrders(self, n: int) -> int:
        MOD = 10**9 + 7
        res = 1
        for i in range(1, n + 1):
            res = res * i * (2 * i - 1) % MOD
        return res
      
class Solution {
public:
    int countOrders(int n) {
        const int MOD = 1e9 + 7;
        long long res = 1;
        for (int i = 1; i <= n; ++i) {
            res = res * i % MOD;
            res = res * (2 * i - 1) % MOD;
        }
        return (int)res;
    }
};
      
class Solution {
    public int countOrders(int n) {
        final int MOD = 1_000_000_007;
        long res = 1;
        for (int i = 1; i <= n; i++) {
            res = res * i % MOD;
            res = res * (2 * i - 1) % MOD;
        }
        return (int)res;
    }
}
      
var countOrders = function(n) {
    const MOD = 1e9 + 7;
    let res = 1;
    for (let i = 1; i <= n; i++) {
        res = res * i % MOD;
        res = res * (2 * i - 1) % MOD;
    }
    return res;
};