80 交错正负数(Interleaving Positive and Negative Numbers)

1 题目

题目:交错正负数(Interleaving Positive and Negative Numbers)
描述:给出一个含有正整数和负整数的数组,重新排列成一个正负数交错的数组。不需要保持正整数或者负整数原来的顺序。

lintcode题号——144,难度——medium

样例1:

输入 : [-1, -2, -3, 4, 5, 6]
输出 : [-1, 5, -2, 4, -3, 6]
解释 : 或者任何满足条件的答案 

2 解决方案

2.1 思路

  先循环一遍提前计算正数和负数的数量,数量较多的数排在第一位,再使用同向双指针的方式,两个指针从头向尾部走,左指针起始位置在0,右指针起始位置在1,假设正数多,左指针找负数,右指针找正数,然后互相交换,将正数排在左指针的位置,负数排在右指针的位置,进行一轮即可排好。

2.2 时间复杂度

  时间复杂度为O(n)。

2.3 空间复杂度

  空间复杂度为O(1)。

3 源码

细节:

  1. 使用同向双指针的方式,指针每次移动2位,right的起始位置比left靠前一位。
  2. 需要提前计算正数和负数的数量,用来判断第一位是正是负。

C++版本:

/*
* @param A: An integer array.
* @return: nothing
*/
void rerange(vector<int> &A) {
    // write your code here
    if (A.size() < 2)
    {
        return;
    }

    // 计算正负数各自的数量
    int positiveCount = 0;
    int negativeCount = 0;
    for (auto it : A)
    {
        if (it > 0)
        {
            positiveCount++;
        }
        else
        {
            negativeCount++;
        }
    }

    // left与right同向移动,每次跳2位,right起始位置比left靠前一位
    int left = 0;
    int right = 1;
    while (left < A.size() && right < A.size())
    {
        if (positiveCount > negativeCount) // 如果正数多,第一位是正数
        {
            if (A.at(left) > 0) // 正数放在left的位置
            {
                left += 2;
                continue;
            }
            if (A.at(right) < 0)
            {
                right += 2;
                continue;
            }

            swap(A.at(left), A.at(right));
            left += 2;
            right += 2;
        }
        else  // 如果负数多,第一位是负数
        {
            if (A.at(left) < 0) // 负数放在left的位置
            {
                left += 2;
                continue;
            }
            if (A.at(right) > 0)
            {
                right += 2;
                continue;
            }

            swap(A.at(left), A.at(right));
            left += 2;
            right += 2;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值