zoukankan      html  css  js  c++  java
  • [LeetCode] 735. Asteroid Collision

    We are given an array asteroids of integers representing asteroids in a row.

    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.

    Example 4:

    Input: 
    asteroids = [-2, -1, 1, 2]
    Output: [-2, -1, 1, 2]
    Explanation: 
    The -2 and -1 are moving left, while the 1 and 2 are moving right.
    Asteroids moving the same direction never meet, so no asteroids will meet each other.

    Note:

    • The length of asteroids will be at most 10000.
    • Each asteroid will be a non-zero integer in the range [-1000, 1000]..

    行星碰撞。题意是给一个数组 asteroids,表示在同一行的行星。对于数组中的每一个元素,其绝对值表示行星的大小,正负表示行星的移动方向(正表示向右移动,负表示向左移动)。每一颗行星以相同的速度移动。找出碰撞后剩下的所有行星。

    碰撞规则:两个行星相互碰撞,较小的行星会爆炸。如果两颗行星大小相同,则两颗行星都会爆炸。两颗移动方向相同的行星,永远不会发生碰撞。

    思路是用stack做。先创建一个空的stack,一开始当stack为空的时候,直接就把数组里面的元素加进去;当stack不为空的时候,做如下判断

    1. 先看一下栈是否为空,若是,则直接加入当前元素

    2. 栈顶元素的正负和要塞入的元素的正负。如果栈顶元素为负(往左)或者要塞入的元素为正(往右),说明加入栈的时候不会发生碰撞,直接就加了;或者栈顶元素跟当前元素同号(同时为正或同时为负),则也不会发生碰撞,直接加入栈

    3. 除了如上的情况,其他情况就有可能会发生碰撞了。这时候判断如果栈顶元素 + 塞入元素 < 0说明两者会相向碰撞并且栈顶元素会被损毁,此时要pop出栈顶元素并且i--,看看试图加入栈的元素能否把新的栈顶元素(原来是在i - 1的位置上的元素)再次损毁

    4. 如果两者相向碰撞但是速度一样,两者互相抵消,栈顶元素直接pop


    或者换一种思路

    1. 如果当前元素为正,无条件加入栈,因为无论栈顶元素正负与否,当前元素都不可能与栈顶元素碰撞

    2. 如果当前元素为负,分如下几种情况

    2.1. 如果栈顶元素为正但是绝对值更小,则说明栈顶元素会被碰撞

    2.2. 如果栈为空,或者栈顶元素也是负数,则不会发生碰撞,将当前元素无条件加入栈内

    2.3. 如果栈不为空,栈顶元素为正且绝对值和当前元素相同,则二者抵消,弹出栈顶元素

    两种实现,在复杂度上都是一样的

    时间O(n)

    空间O(n)

    JavaScript实现

     1 /**
     2  * @param {number[]} asteroids
     3  * @return {number[]}
     4  */
     5 var asteroidCollision = function (asteroids) {
     6     const stack = [];
     7     const len = asteroids.length;
     8     for (let i = 0; i < len; i++) {
     9         const cur = asteroids[i];
    10         // if stack is empty, just push
    11         if (!stack.length) {
    12             stack.push(cur);
    13         } else {
    14             // peek the stack top
    15             const pop = stack[stack.length - 1];
    16             if (pop < 0 || cur > 0) {
    17                 stack.push(cur);
    18             } else if (pop + cur < 0) {
    19                 stack.pop();
    20                 i--;
    21             } else if (pop + cur === 0) {
    22                 stack.pop();
    23             }
    24         }
    25     }
    26     return stack;
    27 };

    Java实现

     1 class Solution {
     2     public int[] asteroidCollision(int[] asteroids) {
     3         // corner case
     4         if (asteroids == null || asteroids.length == 0) {
     5             return new int[0];
     6         }
     7 
     8         // normal case
     9         Stack<Integer> stack = new Stack<>();
    10         for (int i = 0; i < asteroids.length; i++) {
    11             int cur = asteroids[i];
    12             if (cur > 0) {
    13                 stack.push(cur);
    14             } else {
    15                 while (!stack.isEmpty() && stack.peek() > 0 && stack.peek() < Math.abs(cur)) {
    16                     stack.pop();
    17                 }
    18                 if (stack.isEmpty() || stack.peek() < 0) {
    19                     stack.push(cur);
    20                 } else if (stack.peek() + cur == 0) {
    21                     stack.pop();
    22                 }
    23             }
    24         }
    25         int[] res = new int[stack.size()];
    26         for (int i = res.length - 1; i >= 0; i--) {
    27             res[i] = stack.pop();
    28         }
    29         return res;
    30     }
    31 }

    LeetCode 题目总结

  • 相关阅读:
    Orderly Class
    POJ2513 【并查集+欧拉路径+trie树】
    POJ2195 Going Home【KM最小匹配】
    洛谷P2604 最大流+最小费用最大流
    小数转分数
    威尔逊定理
    luogu P6564 [POI2007] 堆积木KLO 树状数组+dp
    Codeforces Round #644 (Div. 3) H——Binary Median 二分
    luogu P4933 大师 线性dp
    Codeforces Round #643 (Div. 2) D——Game With Array
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12316637.html
Copyright © 2011-2022 走看看