剑指offer 专项突破版 37、小行星碰撞

题目链接

思路
  • 小行星碰撞的话,应该把目前扫描到的行星从后往前,和此前扫描的行星依次对比,因此应该想到用栈解决问题
  • 具体的碰撞判断条件为,栈顶的小行星向右(+),此时扫描到的行星向左(-),这样才会碰撞,然后对于碰撞的结果也要分三种情况:
    • 现在的行星大:栈顶弹出,继续判断
    • 一样大:栈顶弹出,结束判断
    • 现在的行星小:结束判断
      这个循环的终止条件为栈空或者是无法碰撞
  • 在碰撞循环结束后要根据不同的条件决定是否要把当前行星加入到栈中
时空复杂度
  • 时间复杂度:每个元素最多入栈、出栈一次,所以是O(n)
  • 空间复杂度:O(n)

注意代码中如何把栈转变为数组~

stars.stream().mapToInt(i -> i).toArray() 

AC代码

class Solution {
    public int[] asteroidCollision(int[] asteroids) {
        Stack<Integer> stars = new Stack<>();

        for (int as : asteroids) {
            boolean isPush = true;
            while (!stars.empty() && stars.peek() > 0 && as < 0) {
                if (stars.peek() > -as) {
                    isPush = false;
                    break;
                } else if (stars.peek() == -as) {
                    isPush = false;
                    stars.pop();
                    break;
                } else
                    stars.pop();
            }

            if (isPush)
                stars.push(as);
        }

        return stars.stream().mapToInt(i -> i).toArray();
    }
}
Go代码
type Stack struct {
	stack []int
}

func (this *Stack) push(num int) {
	this.stack = append(this.stack, num)
}
func (this *Stack) pop() int {
	length := len(this.stack)
	if length == 0 {
		return 0
	}
	num := this.stack[length-1]
	this.stack = this.stack[0 : length-1]
	return num
}
func (this *Stack) top() int {
	if len(this.stack) == 0 {
		return 0
	}
	return this.stack[len(this.stack)-1]
}
func (this *Stack) empty() bool {
	return len(this.stack) == 0
}

func asteroidCollision(asteroids []int) []int {
	stack := &Stack{}

	for _, asteroid := range asteroids {
		if !judgeCollision(stack, asteroid) {
			stack.push(asteroid)
		} else {
			collision(stack, asteroid)
		}
	}
	return stack.stack
}

// 判断是否会撞上
func judgeCollision(stack *Stack, asteroid int) bool {
	if stack.empty() || asteroid > 0 {
		return false
	}
	if asteroid < 0 && stack.top() < 0 {
		return false
	}
	return true
}

func collision(stack *Stack, asteroid int) {
	for !stack.empty() && stack.top() > 0 {
		top := stack.top()
		result := top + asteroid

		if result > 0 {
			return
		} else if result == 0 {
			stack.pop()
			return
		} else {
			stack.pop()
		}
	}
	stack.push(asteroid)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值