【两次过】Lintcode 144. 交错正负数

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

样例

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

挑战

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

注意事项

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


解题思路1:

先用partition操作将数组分为负数与正数两部分。

注意,根据是正数多,还是负数多,起始位置要变一下。正数多,我们希望开始的是正数:例如 3 -1 2。负数多,我们希望开始的是负数,如 -1 3 -2。

最后按位交换即可。

class Solution {
public:
    /*
     * @param A: An integer array.
     * @return: nothing
     */
    void rerange(vector<int> &A) 
    {
        // write your code here
        if(A.size() < 2)
            return;
        
        //partition操作,使前半部分为负数,后半部分为正数
        int i = 0 , j = A.size() - 1;
        int posNum = 0;
        while(i <= j)
        {
            if(A[i] < 0)
                i++;
            else
            {
                posNum++;
                swap(A[i],A[j--]);
            }
        }
        
        //若正数多则应由正数作为首位,反之亦然
        if(posNum > A.size()/2)
            i = 0;
        else
            i = 1;
        //j指向第一个正数位置,要么是在正中间,要么是在中间后一个位置
        j = A.size()/2;
        if(A[j] < 0)
            j++;
        
        //交叉交换     
        while(j < A.size())
        {
            swap(A[i],A[j]);
            i += 2;
            j++;
        }
    }
};

解题思路2:

双指针法,两个指针分别指向交叉的正数和负数。先统计正负数个数,若超过序列长度的一半,则正指针从0开始,反之则负指针从0开始。指针每次跳两位,若指向的数字符号不符,则停止,交换两指针指向的数。

public class Solution {
    /*
     * @param A: An integer array.
     * @return: nothing
     */
    public void rerange(int[] A) {
        //统计正负数的个数
        int posNum = 0;
        int negNum = 0;
        
        for(int i : A){
            if(i > 0)
                posNum++;
            else
                negNum++;
        }
        
        int p = 0, n = 0;
        //如果正数多,则正数指针从0开始,否则从1开始
        if(posNum > negNum)
            n = 1;
        else
            p = 1;
        
        while(p < A.length && n < A.length){
            while(p < A.length && A[p] > 0)
                p += 2;
            while(n < A.length && A[n] < 0)
                n += 2;
            //此时p指向第一个不是正数的位置
            //n指向第一个不是负数的位置

            if(p >= A.length || n >= A.length)
                break;
            
            swap(A, p, n);
        }
    }
    
    private void swap(int[] nums, int i, int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值