题目:
给定一个整数数组 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 。
解题思路:
首先看懂题目,绝对值代表小行星的大小,正向右移动,负向左移动,碰撞,绝对值小的行星消失,绝对值相同的都消失。首先我们先将值一个一个填入kong列表中,并将要填的值与kong列表最后一个值进行比较,按规则填。最后将值全部填入kong中,在进行判断是否全为正或全为负,若是则直接输出,若不是进行下一步判断,是否为左边全为负,右边全为正的特殊情况,若是则输出,否则在回到一开始的步骤。
代码:
class Solution(object):
def asteroidCollision(self, asteroids):
"""
:type asteroids: List[int]
:rtype: List[int]
"""
while True:
l = 0
kong = []
k = 0
for i in range(len(asteroids)):
if len(kong) == 0 :
kong.append(asteroids[i])
k+=1
else:
# 符号相同或一个左边的向左,右边的向右,永远撞不到
if (kong[k-1] <0 and asteroids[i] > 0) or ((asteroids[i] * kong[k-1]) > 0):
kong.append(asteroids[i])
k += 1
#符号不同
elif (asteroids[i] ^ kong[k-1]) < 0:
#判断大小,大的留下
if abs(asteroids[i]) < abs(kong[k-1]):
continue
#相同的都消失
elif abs(asteroids[i]) == abs(kong[k-1]):
#此处不用remove是因为会误删前面与删除元素相同的值
kong.pop(k-1)
k -= 1
else:
kong[k-1] = asteroids[i]
#kong中有符号相反的返回True
# 相同则返回False
has_opposite = any((kong[i] * kong[i + 1] < 0) for i in range(len(kong) - 1))
special = False
if has_opposite:
if kong[0] < 0:
#特殊情况,kong中左边全为负右边全为正,不会相撞
for j in range(len(kong)-1):
#如果有两次相邻数相乘小于0则代表不是特殊情况
if kong[j]*kong[j+1]<0:
l+=1
if l>1:
break
if l == 1:
special = True
#要么是特殊情况且不是只有两个值,要么是已经相撞完成全为正或全为负
if has_opposite == False or (special == True and has_opposite== True):
break
else:
temp = asteroids[:]
asteroids = kong[:]
return kong