• [Stack]行星碰撞


    735. 行星碰撞

    给定一个整数数组 asteroids,表示在同一行的行星。

    对于数组中的每一个元素,其绝对值表示行星的大小,正负表示行星的移动方向(正表示向右移动,负表示向左移动)。每一颗行星以相同的速度移动。

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

    示例 1:
    输入:asteroids = [5,10,-5]
    输出:[5,10]
    解释:10 和 -5 碰撞后只剩下 10 。 5 和 10 永远不会发生碰撞。
        
    示例 2:
    输入:asteroids = [8,-8]
    输出:[]
    解释:8 和 -8 碰撞后,两者都发生爆炸。
        
    示例 3:
    输入:asteroids = [10,2,-5]
    输出:[10]
    解释:2 和 -5 发生碰撞后剩下 -5 。10 和 -5 发生碰撞后剩下 10 。
        
    示例 4:
    输入:asteroids = [-2,-1,1,2]
    输出:[-2,-1,1,2]
    解释:-2 和 -1 向左移动,而 1 和 2 向右移动。 由于移动方向相同的行星不会发生碰撞,所以最终没有行星发生碰撞。 
    

    通过题目分析,可以遍历asteroids数组,然后用stack记录碰撞结果,碰撞结果该怎么分析呢?

    • 碰撞场景:
      • 如果栈顶元素是负数,无论当前元素正或者负,都不发生碰撞,可以直接入栈
      • 如果当前元素为正数,无论栈顶元素正或者负,都不发生碰撞,可以直接入栈
    • 通过碰撞场景分析可知,只有栈顶元素为正数并且当前元素为负数时,才会产生碰撞
      • 如果栈顶元素stack.peek()大于abs(asteroides[i]),当前元素不入栈
      • 如果栈顶元素stack.peek()等于abs(asteroides[i]),销毁栈顶元素,并且当前元素不入栈
      • 如果栈顶元素stack.peek()小于abs(asteroides[i]),栈顶弹出,并循环执行碰撞分析场景,循环完成后,当前元素入栈
    public int[] asteroidCollision(int[] asteroids) {
        Deque<Integer> stack = new LinkedList<>();
        for (int asteroid : asteroids) {
            condition:
            {
                while (!stack.isEmpty() && asteroid < 0 && stack.peek() > 0) {
                    if (stack.peek() > -asteroid) {
                        break condition;
                    } else if (stack.peek() < -asteroid) {
                        stack.pop();
                        continue;
                    } else if (stack.peek() == -asteroid) {
                        stack.pop();
                    }
                }
            }
            stack.push(asteroid);
        }
        int[] ans = new int[stack.size()];
        for (int t = ans.length - 1; t >= 0; --t) {
            ans[t] = stack.pop();
        }
        return ans;
    }
    

    上述代码有break label的操作,可用通过设置boolean标记位达到同样的效果

    // 模板代码
    public void process(int[] array) {
        Deque<Integer> stack = new LinkedList<>();
        for (int num : array) {
            while (!stack.isEmpty()) {
                // coding logic
            }
            stack.push(num);
        }
    }
    
  • 相关阅读:
    P1182 数列分段Section II
    P1119 灾后重建
    P1133 教主的花园
    P1077 摆花
    P2002 消息扩散
    P2341 [HAOI2006]受欢迎的牛(tarjan+缩点)
    luoguP1726 上白泽慧音
    P1053 篝火晚会
    P2296 寻找道路
    P1156 垃圾陷阱
  • 原文地址:https://www.cnblogs.com/ffopen/p/15707758.html
Copyright © 2020-2023  润新知