给出一个含有正整数和负整数的数组,重新排列成一个正负数交错的数组。
给出数组[-1, -2, -3, 4, 5, 6]
,重新排序之后,变成[-1, 5, -2, 4, -3, 6]
或者其他任何满足要求的答案
原地完成,没有额外的空间
不需要保持正整数或者负整数原来的顺序。
先用partition操作将数组分为负数与正数两部分。
注意,根据是正数多,还是负数多,起始位置要变一下。正数多,我们希望开始的是正数:例如 3 -1 2。负数多,我们希望开始的是负数,如 -1 3 -2。
最后按位交换即可。
class Solution {
public:
/*
* @param A: An integer array.
* @return: nothing
*/
void rerange(vector &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++;
}
}
};
双指针法,两个指针分别指向交叉的正数和负数。先统计正负数个数,若超过序列长度的一半,则正指针从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;
}
}