You are given a plank of length n
. There are several ants on the plank, each at a unique position. Some ants move to the left, and others move to the right. When two ants meet, they turn around and start moving in the opposite direction, but this is indistinguishable from them simply passing through each other and continuing in their original directions. When an ant reaches either end of the plank (position 0
or n
), it falls off.
You are given:
n
, the length of the plank.left
containing the starting positions of ants moving left.right
containing the starting positions of ants moving right.Constraints: Each ant moves at a speed of 1 unit per second. Each ant starts at a unique position. No two ants start at the same position.
At first glance, it might seem that we need to simulate the movement of every ant and track their collisions, possibly updating their directions each time they meet. This approach would be complicated and inefficient, especially for large inputs.
However, the problem notes that when two ants meet and turn around, it is indistinguishable from them just passing through each other. This is a crucial insight: we can ignore collisions entirely and simply track when each ant falls off the plank.
Therefore, for each ant, the time it takes to fall off is:
n
(which is n - position
).Let's break down the steps to solve the problem efficiently:
left
array, its time to fall off is its current position (since it moves left to 0).right
array, its time to fall off is n - position
(since it moves right to n
).Why does this work? Because the indistinguishability of collisions means we can treat each ant's journey as independent, and the last ant to fall off determines the answer.
Example:
n = 4
left = [4,3]
right = [0,1]
left
:
right
:
So, the last moment before all ants have fallen off is at time 4.
class Solution:
def getLastMoment(self, n: int, left: List[int], right: List[int]) -> int:
max_left = max(left) if left else 0
max_right = max((n - x) for x in right) if right else 0
return max(max_left, max_right)
class Solution {
public:
int getLastMoment(int n, vector<int>& left, vector<int>& right) {
int max_left = 0;
for (int x : left) max_left = max(max_left, x);
int max_right = 0;
for (int x : right) max_right = max(max_right, n - x);
return max(max_left, max_right);
}
};
class Solution {
public int getLastMoment(int n, int[] left, int[] right) {
int maxLeft = 0;
for (int x : left) maxLeft = Math.max(maxLeft, x);
int maxRight = 0;
for (int x : right) maxRight = Math.max(maxRight, n - x);
return Math.max(maxLeft, maxRight);
}
}
var getLastMoment = function(n, left, right) {
let maxLeft = left.length ? Math.max(...left) : 0;
let maxRight = right.length ? Math.max(...right.map(x => n - x)) : 0;
return Math.max(maxLeft, maxRight);
};
Brute-force Approach: If we tried to simulate every ant's movement and every collision, the time complexity would be much higher, potentially O(n^2)
due to the need to update positions for each time step and handle interactions.
Optimized Approach:
left
and right
arrays to find the maximum value in each (or compute n - x
for right
ants). This is O(L + R)
, where L
and R
are the lengths of the two arrays.O(1)
extra space, since we only use a few variables for tracking maxima.This is very efficient and easily handles large input sizes.
The key insight in this problem is realizing that collisions between ants do not affect the time it takes for them to fall off the plank. By treating each ant's movement independently, we can simply calculate the time for each ant to reach the nearest end and return the maximum of those times. This leads to a clean, efficient, and elegant solution.