You are given a list of people waiting in line, where each person has a specific weight, represented as an array weights
. The bus has a maximum weight capacity, given by limit
. People board the bus in the order they appear in the weights
array, one by one.
Your task is to determine the index (0-based) of the last person who can successfully board the bus without exceeding the weight limit. If the next person in line would cause the total weight to exceed limit
, they cannot board, and the process stops.
For example, given weights = [100, 200, 150, 80]
and limit = 400
, the result should be 2
because the first three people (100 + 200 + 150 = 450) would exceed the limit, but only the first two (100 + 200 = 300) are under the limit, so the last person who can board is at index 1. (The example is for illustration; the actual logic will be clarified in the walkthrough.)
The problem is essentially about simulating a queue where people board a bus one after another, and we keep track of the running total of their weights. Once the running total would exceed the bus's weight limit by adding the next person, we stop and return the index of the last person who successfully boarded.
The brute-force way would be to try every possible combination of people, but since the boarding order is fixed and we cannot skip anyone, this simplifies the problem: we only need to add up weights in order and stop as soon as we reach or exceed the limit.
The optimization comes from realizing that a single pass through the array, maintaining a cumulative sum, is sufficient. There's no need for nested loops or backtracking, as the order is fixed and the process is deterministic.
Let's break down the algorithm step by step:
weights
array, add it to the cumulative sum.
limit
.
This approach is efficient because it only requires a single pass through the input, and at each step, we do a simple addition and comparison.
Let's use the following example:
weights = [100, 200, 150, 80]
limit = 400
Let's walk through each step:
If all people fit (e.g., weights = [50, 50, 50]
and limit = 200
), then we would return index 2.
Brute-force approach: If we tried all possible combinations or permutations, it would be O(2^n), but since the order is fixed, this doesn't apply.
Optimized approach:
weights
array. We only make a single pass through the array.
This efficiency is possible because we never need to store or revisit previous states—each decision depends only on the running total.
def lastPersonToFit(weights, limit):
total = 0
for i, w in enumerate(weights):
if total + w > limit:
return i - 1
total += w
return len(weights) - 1
int lastPersonToFit(vector<int>& weights, int limit) {
int total = 0;
for (int i = 0; i < weights.size(); ++i) {
if (total + weights[i] > limit) {
return i - 1;
}
total += weights[i];
}
return weights.size() - 1;
}
public int lastPersonToFit(int[] weights, int limit) {
int total = 0;
for (int i = 0; i < weights.length; i++) {
if (total + weights[i] > limit) {
return i - 1;
}
total += weights[i];
}
return weights.length - 1;
}
function lastPersonToFit(weights, limit) {
let total = 0;
for (let i = 0; i < weights.length; i++) {
if (total + weights[i] > limit) {
return i - 1;
}
total += weights[i];
}
return weights.length - 1;
}
The key insight to this problem is that we only need to simulate the boarding process by maintaining a running sum of weights. As soon as adding the next person would exceed the bus's weight limit, we know the previous person was the last one to successfully board. This leads to a simple, efficient O(n) solution that is easy to implement and understand.
By focusing on the cumulative sum and stopping at the right moment, we avoid unnecessary complexity and deliver a solution that is both elegant and practical.