1. 程式人生 > >leetcode----735. 行星碰撞

leetcode----735. 行星碰撞

735. 行星碰撞 https://leetcode-cn.com/problems/asteroid-collision/

給定一個整數陣列 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 的長度不超過 10000
  • 每一顆行星的大小都是非零整數,範圍是 [-1000, 1000] 。

思路1:使用0標記處理過的。

class Solution {
public:
    vector<int> asteroidCollision(vector<int>& asteroids) {
    	bool isexchanged=false;
    	int n=asteroids.size();
    	int istart=0;
    	do{
	    	isexchanged=false;
            istart=0;
	    	for(int i=istart;i<n;i++)
	    	{
	    		if(asteroids[i]<=0) continue;
	    		int k=1;
                while(i+k<n&&asteroids[i+k]==0) k++;
                if(asteroids[i+k]>0) {i=i+k-1; continue; }
                
	    		if(i+k<n)
	    		{
		    		if(abs(asteroids[i])>abs(asteroids[i+k]))
		    		asteroids[i+k]=0;
		    		else if(abs(asteroids[i])<abs(asteroids[i+k]))
		    		asteroids[i]=0;
		    		else 
		    		{
		    		  asteroids[i]=0;	
		    		  asteroids[i+k]=0;
		    		}
		    		isexchanged=true;
		    	}
		    	istart=i;
	    	}
	    	
	    }while(isexchanged);
        
        vector<int> t;
        for(int i=0;i<n;i++)
            if(asteroids[i])
           t.push_back(asteroids[i]);     
        return t;
    }
};

解法2:使用堆疊

class Solution {
public:
    vector<int> asteroidCollision(vector<int>& asteroids) {
        vector<int> ans;
        if(asteroids.empty())
            return ans;
        stack<int> st;
        int len = asteroids.size();
        for(int i = 0;i < len;i++){
            if(st.empty() || (st.top() < 0 && asteroids[i] > 0) || (st.top() * asteroids[i] > 0)) //如果棧為空、當前行星和棧頂行星相背或同向執行,就入棧
                st.push(asteroids[i]);
            else if(abs(st.top()) == abs(asteroids[i])) //如果當前行星和棧頂行星相向而行且大小相同,同時爆炸
                st.pop();
            else if(abs(st.top()) < abs(asteroids[i])){ //如果當前行星和棧頂行星相向而行且大小相同,棧頂小於當前
                bool flag = true; //flag標識當前行星是否會爆炸
                while(!st.empty() && st.top() > 0 && abs(st.top()) <= abs(asteroids[i])){
                    if(abs(st.top()) == abs(asteroids[i])){
                        flag = false;
                        st.pop();
                        break;
                    }
                    st.pop();
                }
                    
                if(flag && (st.empty() || (st.top() * asteroids[i] > 0)))
                    st.push(asteroids[i]);
            }
        }
        len = st.size();
        ans.resize(len);
        for(int i = len - 1;i >= 0;i--){
            ans[i] = st.top();
            st.pop();
        }
        return ans;
    }
};