735. Asteroid Collision
MediumDescription
給定整數陣列
asteroids代表在同一列中的小行星。正數表示向右移動,負數表示向左移動,絕對值代表大小。兩個小行星相遇時,較小的會爆炸;若大小相同則同時爆炸。同方向的小行星永遠不會相遇。回傳碰撞後的狀態。
Example:
Input: asteroids = [5,10,-5] Output: [5,10]
Intuition#
核心思路:用堆疊處理碰撞,只有「棧頂向右、新元素向左」時才會發生碰撞,反覆比較直到碰撞結束。
- 向右的小行星(正數)不會和之前向右的碰撞,直接入棧
- 向左的小行星(負數)會和之前向右的碰撞,需要逐一比較
- 碰撞結果有三種:新的爆炸、棧頂爆炸、同歸於盡
Approaches#
⭐1: Stack 模擬碰撞#
- 概念: 遍歷小行星,正數直接 push。負數則與棧頂比較:棧頂較小就 pop 掉(繼續比較),棧頂較大就跳過新元素,一樣大就都移除
- 時間複雜度:
O(n)- 每個小行星最多入棧出棧各一次 - 空間複雜度:
O(n)
class Solution {
fun asteroidCollision(asteroids: IntArray): IntArray {
val stack = ArrayDeque<Int>()
for (ast in asteroids) {
var alive = true
while (alive && ast < 0 && stack.isNotEmpty() && stack.last() > 0) {
if (stack.last() < -ast) {
// 棧頂較小,爆炸
stack.removeLast()
} else if (stack.last() == -ast) {
// 同大,同歸於盡
stack.removeLast()
alive = false
} else {
// 棧頂較大,新的爆炸
alive = false
}
}
if (alive) {
stack.addLast(ast)
}
}
return stack.toIntArray()
}
}🔑 Takeaways#
- Pattern: 元素之間有「衝突/消除」關係時,堆疊可以有效模擬
- 關鍵技巧: 用布林變數
alive追蹤新元素是否存活,清晰地處理三種碰撞結果。注意碰撞條件:只有「棧頂 > 0 且新元素 < 0」才會碰撞