We are given an array asteroids of integers representing asteroids in a row. The indices of the asteriod in the array represent their relative position in space.
For each asteroid, the absolute value represents its size, and the sign represents its direction (positive meaning right, negative meaning left). Each asteroid moves at the same speed.
Find out the state of the asteroids after all collisions. If two asteroids meet, the smaller one will explode. If both are the same size, both will explode. Two asteroids moving in the same direction will never meet.
Example 1:
Input: asteroids = [5,10,-5] Output: [5,10] Explanation: The 10 and -5 collide resulting in 10. The 5 and 10 never collide.
Example 2:
Input: asteroids = [8,-8] Output: [] Explanation: The 8 and -8 collide exploding each other.
Example 3:
Input: asteroids = [10,2,-5] Output: [10] Explanation: The 2 and -5 collide resulting in -5. The 10 and -5 collide resulting in 10.
Constraints:
2 <= asteroids.length <= 104-1000 <= asteroids[i] <= 1000asteroids[i] != 0When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We have a collection of celestial rocks moving in space. Some are moving towards each other. The brute force way to figure out what happens is to consider every possible pair of rocks that could collide and see what the outcome is, then repeat this process until no more collisions can happen.
Here's how the algorithm would work step-by-step:
def asteroid_collision_brute_force(asteroids):
while True:
original_asteroids_count = len(asteroids)
next_asteroids_state = list(asteroids)
collision_occurred_in_this_pass = False
# Iterate through all possible pairs of adjacent asteroids
for first_asteroid_index in range(len(next_asteroids_state) - 1):
# Check if the current pair of asteroids are moving towards each other
if next_asteroids_state[first_asteroid_index] > 0 and next_asteroids_state[first_asteroid_index + 1] < 0:
first_asteroid_size = abs(next_asteroids_state[first_asteroid_index])
second_asteroid_size = abs(next_asteroids_state[first_asteroid_index + 1])
if first_asteroid_size > second_asteroid_size:
# The second asteroid is destroyed, remove it from the list
next_asteroids_state.pop(first_asteroid_index + 1)
collision_occurred_in_this_pass = True
break # Restart the scan from the beginning due to list modification
elif first_asteroid_size < second_asteroid_size:
# The first asteroid is destroyed, remove it from the list
next_asteroids_state.pop(first_asteroid_index)
collision_occurred_in_this_pass = True
break # Restart the scan from the beginning due to list modification
else:
# Both asteroids are destroyed, remove both from the list
next_asteroids_state.pop(first_asteroid_index + 1)
next_asteroids_state.pop(first_asteroid_index)
collision_occurred_in_this_pass = True
break # Restart the scan from the beginning due to list modification
asteroids = next_asteroids_state
# If no collisions occurred in this entire pass, the simulation is complete
if not collision_occurred_in_this_pass:
break
return asteroids
We can simulate the asteroid collisions by keeping track of the asteroids that are still in play. As new asteroids appear, we check if they will collide with any existing ones and resolve those collisions until no more collisions occur.
Here's how the algorithm would work step-by-step:
def asteroid_collision(asteroids_in_motion):
surviving_asteroids = []
for current_asteroid in asteroids_in_motion:
while surviving_asteroids and current_asteroid < 0 and surviving_asteroids[-1] > 0:
# Incoming asteroid is moving left and the last surviving is moving right, potential collision.
incoming_asteroid_size = abs(current_asteroid)
last_surviving_asteroid_size = surviving_asteroids[-1]
if incoming_asteroid_size > last_surviving_asteroid_size:
# The asteroid in the holding area is destroyed, continue checking.
surviving_asteroids.pop()
continue
elif incoming_asteroid_size == last_surviving_asteroid_size:
# Both asteroids are destroyed.
surviving_asteroids.pop()
# Break the inner loop as the current asteroid is destroyed.
break
else:
# The incoming asteroid is destroyed.
# Break the inner loop as the current asteroid is destroyed.
break
else:
# This 'else' belongs to the 'while' loop.
# If the inner loop completed without a 'break', it means the current asteroid survived.
# This happens if the surviving_asteroids list is empty, or if the current asteroid is moving right,
# or if the last surviving asteroid is also moving left.
surviving_asteroids.append(current_asteroid)
return surviving_asteroids| Case | How to Handle |
|---|---|
| Empty input array | An empty input array should result in an empty output array. |
| Input array with a single asteroid | An input array with one asteroid should return that single asteroid as the result. |
| All asteroids moving in the same direction (all positive or all negative) | No collisions will occur, and the original array should be returned. |
| Asteroids of equal size colliding | Both asteroids should explode and be removed from the simulation. |
| A right-moving asteroid followed by a smaller left-moving asteroid | The smaller left-moving asteroid should explode, and the right-moving asteroid should continue. |
| A left-moving asteroid followed by a smaller right-moving asteroid | No collision will occur as they are moving away from each other. |
| A large right-moving asteroid followed by a smaller left-moving asteroid | The smaller left-moving asteroid explodes, and the larger right-moving asteroid continues unaffected. |
| A large left-moving asteroid followed by a smaller right-moving asteroid | No collision will occur as they are moving away from each other. |