面试官对原题做了修改,请注意对比不同。
题目描述:行星碰撞
1、给定一个整数数组
planets,
表示在同一行的行星。
2、对于数组中的每一个元素,其绝对值表示行星的大小,正负表示行星的移动方向(正表示向左移动,负表 示向右移动)。每一颗行星以相同的速度移动。
3、找出碰撞后身下的所有行星。碰撞规则:两个行星相互碰撞,较小的行星会爆炸。如果两颗行星大小相 同,则两颗行星都会爆炸。两颗移动方向相同的行星,永远不会发生碰撞。
示例
1
:
输入:
planets = [-5,-10,5]
输出:
[-5,-10]
解释:
-10
和
5
进行碰撞后只剩下
-10
,
-5
和
-10
永远不会发生碰撞
示例
2
:
输入:
planets = [-8,8]
输出:
[]
解释:
-8
和
8
进行碰撞后,全部行星都爆炸了。剩下为空。
代码实现:
public static void main(String[] args) {
int[] plants = {-8,8};
int[] res = getRes(plants);
for (int item : res) {
System.out.println(item);
}
}
//思路:用栈的思想去实现:
题目描述
//负数直接入栈,用正数去和栈顶元素抵消(相同才能抵消,不同的时候留下值大的)
//抵消后还是整数的话,继续和栈顶元素进行抵消,直到不能抵消为止。
//最后栈中剩余的元素就是想要的结果
//举例:-5, -10, 5
// -5 先入栈 -10来了后也直接入栈 5来了以后和-10比较,留下-10,所以最后结果是
[-5,-10]
//1、栈中没有元素的时候,小于0的直接将值入栈
//2、遇到正数且栈中有元素的时候,当前正数与栈顶元素进行比较,如果正数大于负数的相反值
则碰撞未完全抵消
//那么继续循环去抵消 若完全抵消 则循环终止 每抵消一个 出栈一个元素 若flag扔为true
代表当前是负数
// 则当前遍历入栈
public static int[] getRes(int[] planets) {
Stack<Integer> stack = new Stack<>();
for (int planet : planets) {
boolean flag = true;//是否要添加到栈中
while (flag && planet > 0 && !stack.isEmpty() && stack.peek() <
0) {//元素为正数且栈不为空,且栈顶为负数
flag = stack.peek() > -planet; //栈顶与遍历值的相反数是否可以碰撞
if (stack.peek() >= -planet) { // 栈顶小行星爆炸,也就是要弹栈
stack.pop();
}
}
if (flag) {
stack.push(planet);
}
}
int size = stack.size();
int[] ans = new int[size];
for (int i = size - 1; i >= 0; i--) {
ans[i] = stack.pop();
}
return ans;
}