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 源码
细节:
- 使用同向双指针的方式,指针每次移动2位,right的起始位置比left靠前一位。
- 需要提前计算正数和负数的数量,用来判断第一位是正是负。
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;
}
}
}