lintcode-交错正负数-144

给出一个含有正整数和负整数的数组,重新排列成一个正负数交错的数组。


样例

给出数组[-1, -2, -3, 4, 5, 6],重新排序之后,变成[-1, 5, -2, 4, -3, 6]或者其他任何满足要求的答案

注意

不需要保持正整数或者负整数原来的顺序。

挑战

原地完成,没有额外的空间

class Solution {
public:
    void rerange(vector<int> &vec){
            int  i=0,j=1; 
	    int  count=0,n=vec.size();
	    bool flag=false;
	    for(auto e:vec)
	        if(e<0)
		    ++count;   //记录负数的个数
	    if(n-count>count)  
	        flag=true;
	    
            //当正数个数大于负数个数时,第一个元素一定是正数,此时i和j分别表示正数行(下标为偶数)
            //和负数行(下标为奇数)
	    if(flag) while(i<n&&j<n){
	        int findi=-1,findj=-1;
		    if(vec[i]<0){       //当vec[i]为负时(i是指向正数行的下标),需要改变
		        int findi=i+1;  //findi从负数行(下标为奇数)查找(可以检验出负数行大致排位)
			    while(findi<n&&vec[findi]<0)
				   findi+=2;
			    if(findi<n)//找到一个正数后交换,此时不难猜出负数行区间
                                       //(从i+1到findi)必然全为负数,j可以直接跳到findi+2
				    swap(vec[findi],vec[i]);
		    }
	            if(vec[j]>0){
		        int findj=j+1;
			    while(findj<n&&vec[findj]>0)
				    findj+=2;
			    if(findj<n)
			        swap(vec[findj],vec[j]);
		    }
		    if(-1!=findi)
			    j=findi; //前面已经说了findi是运行在负数行的
		    if(-1!=findj)
			    i=findj;
		    i+=2,j+=2;      //移动的步数
            //用纸和笔比划一遍就可以马上理解大体的思路,光看肯定不理解,但其实思路很简单 
	    }
	    else while(i<n&&j<n){
	        int findi=-1,findj=-1;
		if(vec[i]>0){
		    int findi=i+1;
		    while(findi<n&&vec[findi]>0)
		        findi+=2;
		    if(findi<n)
		        swap(vec[findi],vec[i]);
		    }
	        if(vec[j]<0){
		        int findj=j+1;
			    while(findj<n&&vec[findj]<0)
				    findj+=2;
			    if(findj<n)
			        swap(vec[findj],vec[j]);
		    }
		    if(-1!=findi)
			    j=findi;
		    if(-1!=findj)
			    i=findj;
			i+=2,j+=2; 
	    }
    }
};


你可能感兴趣的:(lintcode-交错正负数-144)