[LintCode] Interleaving Positive and Negative Numbers

455 查看

Problem

Given an array with positive and negative integers. Re-range it to interleaving with positive and negative integers.

Notice

You are not necessary to keep the original order of positive integers or negative integers.

Example

Given [-1, -2, -3, 4, 5, 6], after re-range, it will be [-1, 5, -2, 4, -3, 6] or any other reasonable answer.

Challenge

Do it in-place and without extra memory.

Note

典型双指针题目,两个指针分别指向交叉的正数和负数。
注意,若正数多于负数,则序列以正数开始,正数结束。所以先统计正数个数,若超过序列长度的一半,则正指针从0开始,反之则负指针从0开始。指针每次跳两位,若指向的数字符号不符,则停止,交换两指针指向的数。
注意交换函数swap()的形式,必须是交换指针所指数字的值,而非坐标。所以下面这样的写法是不对的:swap(A[posIndex], A[negIndex]),因为它调用的是swap(integerA, integerB),在交换值的同时也交换了坐标。

Solution

class Solution {
    public void rerange(int[] A) {
        int posNum = 0, posIndex = 1, negIndex = 0;
        for (int a : A) {
            posNum += a > 0 ? 1 : 0;
        }
        if (posNum * 2 > A.length) {
            posIndex = 0;
            negIndex = 1;
        }
        while (posIndex < A.length && negIndex < A.length) {
            while (posIndex < A.length && A[posIndex] > 0) posIndex += 2;
            while (negIndex < A.length && A[negIndex] < 0) negIndex += 2;
            if (posIndex < A.length && negIndex < A.length) {
                swap(A, posIndex, negIndex);
                posIndex += 2;
                negIndex += 2;
            }
        }
    }
    public void swap(int[] A, int i, int j) {
        int temp = A[i];
        A[i] = A[j];
        A[j] = temp;
    }
}