Leetcode算法学习日志-735 Asteroid Collision

1 篇文章 0 订阅
1 篇文章 0 订阅

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.

题意分析

给定一个只有正数和负数的数组,数值代表小行星的质量,正负代表运行方向,正向右,负向左。如果两个小行星碰上,则质量小的会爆炸,留下质量大的,如果质量一样则两个都消失,问最终留存的小行星数组。

解法分析

本题我采用两种方法解决:

  • 分治策略

分治策略

本题可以将数组分成两部分,每一部分进行行星碰撞,得到完成后的left,right两部分数组再进行碰撞,此时只有一种情况左右两部分会碰撞,即左边部分的末尾是正数,右边部分末尾是负数,其他情况只需要将left和right连接即可。注意算法中访问了vector的元素,要避免访问越界,比如当right为空时,需要先判断。C++代码如下:

class Solution {
public:
    vector<int> divide(int start,int end,vector<int>& asteroids){
        vector<int> res;
        if(start==end){
            res.push_back(asteroids[start]);
            return res;
        }
               
        int mid=(start+end)/2;
        vector<int> left=divide(start,mid,asteroids);
        vector<int> right=divide(mid+1,end,asteroids);
        if(!(left.empty())&&!(right.empty())){
            if(left[left.size()-1]>0&&right[0]<0){//{- - + +}{- - + +}the two parts will meet,to access right[0],right can't be empty
            int i=left.size()-1,j=0;
            while(left[i]>0&&right[j]<0){
                if(left[i]>(-right[j])){
                    right.erase(right.begin()+j);
                    if(right.empty())
                        break;
                }
                else if(left[i]<(-right[j])){
                    left.erase(left.begin()+i);
                    if(left.empty())
                        break;
                    i--;
                }
                else{
                    right.erase(right.begin()+j);
                    left.erase(left.begin()+i);
                    if(right.empty()||left.empty())
                        break;
                    i--;
                }
                    
            }
        }
        }
        res.insert(res.end(),left.begin(),left.end());
        res.insert(res.end(),right.begin(),right.end());
        return res;
    }
    vector<int> asteroidCollision(vector<int>& asteroids) {
        vector<int> res;
        if(asteroids.size()==0)
            return res;
        return divide(0,asteroids.size()-1,asteroids);
    }
};

本题还可以将左边已经碰撞完成的元素放入一个栈中(用vector可以模拟栈的操作),依次加入asteroid中的元素,根据加入元素的正负,以及栈顶的正负来决定是哪一个行星消失。C++代码如下:

class Solution {
public:
    vector<int> asteroidCollision(vector<int>& asteroids) {
        vector<int> res;
        int i;
        for(i=0;i<asteroids.size();i++){
            if(res.empty())
                res.push_back(asteroids[i]);
            else if(asteroids[i]>0)
                res.push_back(asteroids[i]);
            else{
                if(res[res.size()-1]<0)
                    res.push_back(asteroids[i]);
                else{
                    if(res[res.size()-1]>(-asteroids[i]))
                        continue;
                    else if(res[res.size()-1]==(-asteroids[i])){
                        res.pop_back();
                        continue;
                    }
                    else{
                        res.pop_back();
                        i--;
                    }                        
                }
            }
        }
        return res;
        
    }
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值