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;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/SeeDoubleU/article/details/124642293