Given an array of integers asteroids, where each integer represents an asteroid in a row, determine the state of the asteroids after all collisions. In this array, the absolute value represents the size of the asteroid, and the sign represents its direction (positive meaning right and negative meaning left). All asteroids move at the same speed.
When two asteroids meet, the smaller one will explode. If they are the same size, both will explode. Asteroids moving in the same direction will never meet.
Input: asteroids = [2, -2]
Output: []
Explanation: The asteroid with size 2 and the one with size -2 collide, exploding each other.
Input: asteroids = [10, 20, -10]
Output: [10, 20]
Explanation: The asteroid with size 20 and the one with size -10 collide, resulting in the remaining asteroid with size 20. The asteroids with sizes 10 and 20 never collide.
Input: asteroids = [10, 2, -5]
· 2 <= asteroids.length <= 105
· -106 <= asteroids[i] <= 106
· asteroids[i] != 0
The first thing to understand is the condition for two asteroids to collide.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
/* Function to determine the state of
asteroids after all collisions */
vector<int> asteroidCollision(vector<int> &asteroids){
// Size of the array
int n = asteroids.size();
// List implementation of stack
vector<int> st;
// Traverse all the asteroids
for(int i=0; i < n; i++) {
/* Push the asteroid in stack if a
right moving asteroid is seen */
if(asteroids[i] > 0) {
st.push_back(asteroids[i]);
}
/* Else if the asteroid is moving
right, perform the collisions */
else {
/* Until the right moving asteroids are
smaller in size, keep on destroying them */
while(!st.empty() && st.back() > 0 &&
st.back() < abs(asteroids[i])) {
// Destroy the asteroid
st.pop_back();
}
/* If there is right moving asteroid
which is of same size */
if(!st.empty() &&
st.back() == abs(asteroids[i])) {
// Destroy both the asteroids
st.pop_back();
}
/* Otherwise, if there is no left
moving asteroid, the right moving
asteroid will not be destroyed */
else if(st.empty() ||
st.back() < 0){
// Storing the array in final state
st.push_back(asteroids[i]);
}
}
}
// Return the final state of asteroids
return st;
}
};
int main() {
vector<int> arr = {10, 20, -10};
/* Creating an instance of
Solution class */
Solution sol;
/* Function call to determine the state of
asteroids after all collisions */
vector<int> ans = sol.asteroidCollision(arr);
cout << "The state of asteroids after collisions is: ";
for(int i=0; i < ans.size(); i++) {
cout << ans[i] << " ";
}
return 0;
}
import java.util.*;
class Solution {
/* Function to determine the state of
asteroids after all collisions */
public int[] asteroidCollision(int[] asteroids) {
// Size of the array
int n = asteroids.length;
// List implementation of stack
List<Integer> st = new ArrayList<>();
// Traverse all the asteroids
for(int i = 0; i < n; i++) {
/* Push the asteroid in stack if a
right moving asteroid is seen */
if(asteroids[i] > 0) {
st.add(asteroids[i]);
}
/* Else if the asteroid is moving
left, perform the collisions */
else {
/* Until the right moving asteroids are
smaller in size, keep on destroying them */
while(!st.isEmpty() && st.get(st.size() - 1) > 0 &&
st.get(st.size() - 1) < Math.abs(asteroids[i])) {
// Destroy the asteroid
st.remove(st.size() - 1);
}
/* If there is right moving asteroid
which is of same size */
if(!st.isEmpty() &&
st.get(st.size() - 1) == Math.abs(asteroids[i])) {
// Destroy both the asteroids
st.remove(st.size() - 1);
}
/* Otherwise, if there is no left
moving asteroid, the right moving
asteroid will not be destroyed */
else if(st.isEmpty() ||
st.get(st.size() - 1) < 0){
// Storing the array in final state
st.add(asteroids[i]);
}
}
}
// Convert list to array
int[] result = new int[st.size()];
for(int i = 0; i < st.size(); i++) {
result[i] = st.get(i);
}
// Return the final state of asteroids
return result;
}
public static void main(String[] args) {
int[] arr = {10, 20, -10};
/* Creating an instance of
Solution class */
Solution sol = new Solution();
/* Function call to determine the state of
asteroids after all collisions */
int[] ans = sol.asteroidCollision(arr);
System.out.print("The state of asteroids after collisions is: ");
for(int i = 0; i < ans.length; i++) {
System.out.print(ans[i] + " ");
}
}
}
class Solution:
def asteroidCollision(self, asteroids):
# Size of the array
n = len(asteroids)
# List implementation of stack
st = []
# Traverse all the asteroids
for i in range(n):
# Push the asteroid in stack if a
# right moving asteroid is seen
if asteroids[i] > 0:
st.append(asteroids[i])
# Else if the asteroid is moving
# left, perform the collisions
else:
# Until the right moving asteroids are
# smaller in size, keep on destroying them
while (st and st[-1] > 0 and
st[-1] < abs(asteroids[i])):
# Destroy the asteroid
st.pop()
# If there is right moving asteroid
# which is of same size
if st and st[-1] == abs(asteroids[i]):
# Destroy both the asteroids
st.pop()
# Otherwise, if there is no left
# moving asteroid, the right moving
# asteroid will not be destroyed
elif not st or st[-1] < 0:
# Storing the array in final state
st.append(asteroids[i])
# Return the final state of asteroids
return st
# Main function to test the solution
if __name__ == "__main__":
arr = [10, 20, -10]
# Creating an instance of Solution class
sol = Solution()
# Function call to determine the state of
# asteroids after all collisions
ans = sol.asteroidCollision(arr)
print("The state of asteroids after collisions is:", ans)
class Solution {
/* Function to determine the state of
asteroids after all collisions */
asteroidCollision(asteroids) {
// Size of the array
let n = asteroids.length;
// List implementation of stack
let st = [];
// Traverse all the asteroids
for (let i = 0; i < n; i++) {
/* Push the asteroid in stack if a
right moving asteroid is seen */
if (asteroids[i] > 0) {
st.push(asteroids[i]);
}
/* Else if the asteroid is moving
left, perform the collisions */
else {
/* Until the right moving asteroids are
smaller in size, keep on destroying them */
while (st.length > 0 && st[st.length - 1] > 0 &&
st[st.length - 1] < Math.abs(asteroids[i])) {
// Destroy the asteroid
st.pop();
}
/* If there is right moving asteroid
which is of same size */
if (st.length > 0 &&
st[st.length - 1] == Math.abs(asteroids[i])) {
// Destroy both the asteroids
st.pop();
}
/* Otherwise, if there is no left
moving asteroid, the right moving
asteroid will not be destroyed */
else if (st.length == 0 ||
st[st.length - 1] < 0){
// Storing the array in final state
st.push(asteroids[i]);
}
}
}
// Return the final state of asteroids
return st;
}
}
// Main function to test the solution
const arr = [10, 20, -10];
/* Creating an instance of
Solution class */
const sol = new Solution();
/* Function call to determine the state of
asteroids after all collisions */
const ans = sol.asteroidCollision(arr);
console.log("The state of asteroids after collisions is:", ans);
Time Complexity: O(N) (where N is the size of the asteroids array)
Space Complexity: O(N)
In the worst case, all asteroids will be stored in the stack if there are no collisions, leading to a space requirement of O(N).
Q: What happens when a larger asteroid collides with a smaller one?
A: The smaller asteroid is removed from the stack, and the larger asteroid continues moving.
Q: Can a single asteroid survive after multiple collisions?
A: Yes, a large negative asteroid can destroy multiple right-moving asteroids before stopping.
Q: How would the problem change if asteroids could bounce instead of exploding?
A: If asteroids bounced off instead of exploding, a queue might be more suitable for handling movement.
Q: How would you modify the solution for 2D space (instead of a single row)?
A: A priority queue or event-driven simulation would be needed to track asteroid movement and interactions in both directions.