You 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 = [2,4,-4,-1]
Output: [2]Example 2:
Input: asteroids = [5,5]
Output: [5,5]Example 3:
Input: asteroids = [7,-3,9]
Output: [7,9]Constraints:
2 <= asteroids.length <= 10,000.-1000 <= asteroids[i] <= 1000asteroids[i] != 0Before attempting this problem, you should be comfortable with:
Collisions only happen when a right-moving asteroid (positive) meets a left-moving one (negative). A stack naturally models this: we process asteroids left to right, and when we see a negative asteroid, it can only collide with positive asteroids already on the stack. We keep popping and comparing until either the new asteroid is destroyed, destroys all opposing asteroids, or there are no more collisions possible.
class Solution:
def asteroidCollision(self, asteroids: List[int]) -> List[int]:
stack = []
for a in asteroids:
while stack and a < 0 and stack[-1] > 0:
diff = a + stack[-1]
if diff < 0:
stack.pop()
elif diff > 0:
a = 0
else:
a = 0
stack.pop()
if a:
stack.append(a)
return stackWe can simulate the stack behavior using the input array itself. We maintain a pointer j that tracks the "top" of our virtual stack within the array. When collisions occur, we decrement j (like popping). Surviving asteroids are written to position j + 1. This gives us O(1) extra space while maintaining the same logic.
j = -1 to represent an empty stack.asteroids[j] when both are in opposite directions.j and store it at asteroids[j].0 to j (inclusive).class Solution:
def asteroidCollision(self, asteroids: List[int]) -> List[int]:
n = len(asteroids)
j = -1
for a in asteroids:
while j >= 0 and asteroids[j] > 0 and a < 0:
if asteroids[j] > abs(a):
a = 0
break
elif asteroids[j] == abs(a):
j -= 1
a = 0
break
else:
j -= 1
if a:
j += 1
asteroids[j] = a
return asteroids[:j + 1]Not all asteroids collide. Two asteroids moving in the same direction (both positive or both negative) never collide. A negative asteroid followed by a positive asteroid also never collide since they move apart.
# Wrong: checking if signs differ without considering direction
if asteroids[i] * asteroids[j] < 0: # collision!
# Right: collision only when positive is before negative
if stack[-1] > 0 and a < 0: # potential collisionA single incoming asteroid can destroy multiple asteroids on the stack. You need a loop, not just a single comparison.
# Wrong: only one comparison
if stack and a < 0 and stack[-1] > 0:
# handle one collision and move on
# Right: keep checking until no more collisions
while stack and a < 0 and stack[-1] > 0:
# handle collision, may need to pop multiple timesWhen comparing asteroid sizes, remember that negative asteroids have negative values. Use absolute value for size comparison.
# Wrong: comparing raw values
if stack[-1] > a: # incorrect when a is negative
# Right: compare magnitudes
if stack[-1] > abs(a): # or equivalently: stack[-1] + a > 0