📌  相关文章
📜  使用 O(1) 额外空间在交替的正负项中重新排列数组 |设置 1

📅  最后修改于: 2022-05-13 01:57:50.781000             🧑  作者: Mango

使用 O(1) 额外空间在交替的正负项中重新排列数组 |设置 1

给定一组正数和负数,以交替方式排列它们,使每个正数后面跟着负数,反之亦然,保持出现顺序。
正数和负数的个数不必相等。如果有更多的正数,它们会出现在数组的末尾。如果有更多的负数,它们也会出现在数组的末尾。

例子 :

Input:  arr[] = {1, 2, 3, -4, -1, 4}
Output: arr[] = {-4, 1, -1, 2, 3, 4}

Input:  arr[] = {-5, -2, 5, 2, 4, 7, 1, 8, 0, -8}
output: arr[] = {-5, 5, -2, 2, -8, 4, 7, 1, 8, 0}

这个问题在很多地方都被问过(见这个和这个)

天真的方法:
如果允许 O(n) 额外的空间,上述问题可以很容易地解决。由于 O(1) 额外空间和出现顺序的限制,它变得很有趣。
这个想法是从左到右处理数组。在处理时,在剩余的未处理数组中找到第一个不合适的元素。如果元素为负且位于奇数索引(基于 0 的索引),或者它为正且位于偶数索引(基于 0 的索引),则元素不合适。一旦我们找到一个不合适的元素,我们就会找到它之后的第一个元素,符号相反。我们在这两个元素(包括这两个元素)之间右旋子数组。

以下是上述思想的实现。

C++
/*  C++ program to rearrange
   positive and negative integers
   in alternate fashion while keeping
   the order of positive and negative numbers. */
#include 
#include 
using namespace std;
 
// Utility function to right rotate all elements between
// [outofplace, cur]
void rightrotate(int arr[], int n, int outofplace, int cur)
{
    char tmp = arr[cur];
    for (int i = cur; i > outofplace; i--)
        arr[i] = arr[i - 1];
    arr[outofplace] = tmp;
}
 
void rearrange(int arr[], int n)
{
    int outofplace = -1;
 
    for (int index = 0; index < n; index++)
    {
        if (outofplace >= 0)
        {
            // find the item which must be moved into the
            // out-of-place entry if out-of-place entry is
            // positive and current entry is negative OR if
            // out-of-place entry is negative and current
            // entry is negative then right rotate
            //
            // [...-3, -4, -5, 6...] -->   [...6, -3, -4,
            // -5...]
            //      ^                          ^
            //      |                          |
            //     outofplace      -->      outofplace
            //
            if (((arr[index] >= 0) && (arr[outofplace] < 0))
                || ((arr[index] < 0)
                    && (arr[outofplace] >= 0)))
            {
                rightrotate(arr, n, outofplace, index);
 
                // the new out-of-place entry is now 2 steps
                // ahead
                if (index - outofplace >= 2)
                    outofplace = outofplace + 2;
                else
                    outofplace = -1;
            }
        }
 
        // if no entry has been flagged out-of-place
        if (outofplace == -1) {
            // check if current entry is out-of-place
            if (((arr[index] >= 0) && (!(index & 0x01)))
                || ((arr[index] < 0) && (index & 0x01))) {
                outofplace = index;
            }
        }
    }
}
 
// A utility function to print an array 'arr[]' of size 'n'
void printArray(int arr[], int n)
{
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";
    cout << endl;
}
 
// Driver code
int main()
{
     
    int arr[] = { -5, -2, 5, 2,
                 4, 7, 1, 8, 0, -8 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    cout << "Given array is \n";
    printArray(arr, n);
 
    rearrange(arr, n);
 
    cout << "Rearranged array is \n";
    printArray(arr, n);
 
    return 0;
}


Java
class RearrangeArray
{
    // Utility function to right rotate all elements
    // between [outofplace, cur]
    void rightrotate(int arr[], int n, int outofplace,
                     int cur)
    {
        int tmp = arr[cur];
        for (int i = cur; i > outofplace; i--)
            arr[i] = arr[i - 1];
        arr[outofplace] = tmp;
    }
 
    void rearrange(int arr[], int n)
    {
        int outofplace = -1;
 
        for (int index = 0; index < n; index++)
        {
            if (outofplace >= 0)
            {
                // find the item which must be moved into
                // the out-of-place entry if out-of-place
                // entry is positive and current entry is
                // negative OR if out-of-place entry is
                // negative and current entry is negative
                // then right rotate
                //
                // [...-3, -4, -5, 6...] -->   [...6, -3,
                // -4, -5...]
                //      ^                          ^
                //      |                          |
                //     outofplace      -->      outofplace
                //
                if (((arr[index] >= 0)
                     && (arr[outofplace] < 0))
                    || ((arr[index] < 0)
                        && (arr[outofplace] >= 0))) {
                    rightrotate(arr, n, outofplace, index);
 
                    // the new out-of-place entry is now 2
                    // steps ahead
                    if (index - outofplace >= 2)
                        outofplace = outofplace + 2;
                    else
                        outofplace = -1;
                }
            }
 
            // if no entry has been flagged out-of-place
            if (outofplace == -1)
            {
                // check if current entry is out-of-place
                if (((arr[index] >= 0)
                     && ((index & 0x01) == 0))
                    || ((arr[index] < 0)
                        && (index & 0x01) == 1))
                    outofplace = index;
            }
        }
    }
 
    // A utility function to print
    // an array 'arr[]' of size 'n'
    void printArray(int arr[], int n)
    {
        for (int i = 0; i < n; i++)
            System.out.print(arr[i] + " ");
        System.out.println("");
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        RearrangeArray rearrange = new RearrangeArray();
        /* int arr[n] = {-5, 3, 4, 5, -6,
                         -2, 8, 9, -1, -4};
        int arr[] = {-5, -3, -4, -5, -6,
                     2 , 8, 9, 1 , 4};
        int arr[] = {5, 3, 4, 2, 1,
                     -2 , -8, -9, -1 , -4};
        int arr[] = {-5, 3, -4, -7,
                     -1, -2 , -8, -9, 1 , -4};*/
        int arr[] = { -5, -2, 5, 2, 4,
                     7, 1, 8, 0, -8 };
        int n = arr.length;
 
        System.out.println("Given array is ");
        rearrange.printArray(arr, n);
 
        rearrange.rearrange(arr, n);
 
        System.out.println("RearrangeD array is ");
        rearrange.printArray(arr, n);
    }
}
 
// This code has been contributed by Mayank Jaiswal


Python
# Python3 program to rearrange
# positive and negative integers
# in alternate fashion and
# maintaining the order of positive
# and negative numbers
 
# rotates the array to right by once
# from index 'outOfPlace to cur'
 
 
def rightRotate(arr, n, outOfPlace, cur):
    temp = arr[cur]
    for i in range(cur, outOfPlace, -1):
        arr[i] = arr[i - 1]
    arr[outOfPlace] = temp
    return arr
 
 
def rearrange(arr, n):
    outOfPlace = -1
    for index in range(n):
        if(outOfPlace >= 0):
 
            # if element at outOfPlace place in
            # negative and if element at index
            # is positive we can rotate the
            # array to right or if element
            # at outOfPlace place in positive and
            # if element at index is negative we
            # can rotate the array to right
            if((arr[index] >= 0 and arr[outOfPlace] < 0) or
               (arr[index] < 0 and arr[outOfPlace] >= 0)):
                arr = rightRotate(arr, n, outOfPlace, index)
                if(index-outOfPlace > 2):
                    outOfPlace += 2
                else:
                    outOfPlace = - 1
 
        if(outOfPlace == -1):
 
            # conditions for A[index] to
            # be in out of place
            if((arr[index] >= 0 and index % 2 == 0) or
               (arr[index] < 0 and index % 2 == 1)):
                outOfPlace = index
    return arr
 
 
# Driver Code
arr = [-5, -2, 5, 2, 4,
       7, 1, 8, 0, -8]
 
print("Given Array is:")
print(arr)
 
print("\nRearranged array is:")
print(rearrange(arr, len(arr)))
 
# This code is contributed
# by Charan Sai


C#
// Rearrange array in alternating positive
// & negative items with O(1) extra space
using System;
 
class GFG {
    // Utility function to right rotate
    // all elements between [outofplace, cur]
    static void rightrotate(int[] arr, int n,
                            int outofplace, int cur)
    {
        int tmp = arr[cur];
        for (int i = cur; i > outofplace; i--)
            arr[i] = arr[i - 1];
        arr[outofplace] = tmp;
    }
 
    static void rearrange(int[] arr, int n)
    {
        int outofplace = -1;
 
        for (int index = 0; index < n; index++) {
            if (outofplace >= 0) {
                // find the item which must be moved
                // into the out-of-place entry if out-of-
                // place entry is positive and current
                // entry is negative OR if out-of-place
                // entry is negative and current entry
                // is negative then right rotate
                // [...-3, -4, -5, 6...] --> [...6, -3, -4,
                // -5...]
                //     ^                         ^
                //     |                         |
                //     outofplace     -->     outofplace
                //
                if (((arr[index] >= 0)
                     && (arr[outofplace] < 0))
                    || ((arr[index] < 0)
                        && (arr[outofplace] >= 0))) {
                    rightrotate(arr, n, outofplace, index);
 
                    // the new out-of-place entry
                    // is now 2 steps ahead
                    if (index - outofplace > 2)
                        outofplace = outofplace + 2;
                    else
                        outofplace = -1;
                }
            }
 
            // if no entry has been flagged out-of-place
            if (outofplace == -1) {
                // check if current entry is out-of-place
                if (((arr[index] >= 0)
                     && ((index & 0x01) == 0))
                    || ((arr[index] < 0)
                        && (index & 0x01) == 1))
                    outofplace = index;
            }
        }
    }
 
    // A utility function to print an
    // array 'arr[]' of size 'n'
    static void printArray(int[] arr, int n)
    {
        for (int i = 0; i < n; i++)
            Console.Write(arr[i] + " ");
        Console.WriteLine("");
    }
 
    // Driver code
    public static void Main()
    {
        int[] arr = { -5, -2, 5, 2, 4, 7, 1, 8, 0, -8 };
        int n = arr.Length;
 
        Console.WriteLine("Given array is ");
        printArray(arr, n);
 
        rearrange(arr, n);
 
        Console.WriteLine("RearrangeD array is ");
        printArray(arr, n);
    }
}
 
// This code is contributed by Sam007


PHP
 $outofplace; $i--)
        $arr[$i] = $arr[$i - 1];
    $arr[$outofplace] = $tmp;
}
 
function rearrange(&$arr, $n)
{
    $outofplace = -1;
 
    for ($index = 0; $index < $n; $index ++)
    {
        if ($outofplace >= 0)
        {
            // find the item which must be moved
            // into the out-of-place entry if
            // out-of-place entry is positive and
            // current entry is negative OR if
            // out-of-place entry is negative
            // and current entry is negative then
            // right rotate
            // [...-3, -4, -5, 6...] --> [...6, -3, -4, -5...]
            //     ^                         ^
            //     |                         |
            //     outofplace     -->     outofplace
            //
            if ((($arr[$index] >= 0) && ($arr[$outofplace] < 0)) ||
                (($arr[$index] < 0) && ($arr[$outofplace] >= 0)))
            {
                rightrotate($arr, $n, $outofplace, $index);
 
                // the new out-of-place entry is
                // now 2 steps ahead
                if ($index - $outofplace > 2)
                    $outofplace = $outofplace + 2;
                else
                    $outofplace = -1;
            }
        }
 
        // if no entry has been flagged out-of-place
        if ($outofplace == -1)
        {
            // check if current entry is out-of-place
            if ((($arr[$index] >= 0) && (!($index & 0x01)))
                || (($arr[$index] < 0) && ($index & 0x01)))
            {
                $outofplace = $index;
            }
        }
    }
}
 
// A utility function to print an
// array 'arr[]' of size 'n'
function printArray(&$arr, $n)
{
    for ($i = 0; $i < $n; $i++)
    echo $arr[$i]." ";
    echo "\n";
}
 
// Driver Code
 
// arr = array(-5, 3, 4, 5, -6, -2, 8, 9, -1, -4);
// arr = array(-5, -3, -4, -5, -6, 2 , 8, 9, 1 , 4);
// arr = array(5, 3, 4, 2, 1, -2 , -8, -9, -1 , -4);
// arr = array(-5, 3, -4, -7, -1, -2 , -8, -9, 1 , -4);
$arr = array(-5, -2, 5, 2, 4, 7, 1, 8, 0, -8);
$n = sizeof($arr);
 
echo "Given array is \n";
printArray($arr, $n);
 
rearrange($arr, $n);
 
echo "Rearranged array is \n";
printArray($arr, $n);
 
// This code is contributed by ChitraNayal
?>


Javascript


输出
Given array is 
-5 -2 5 2 4 7 1 8 0 -8 
Rearranged array is 
-5 5 -2 2 -8 4 7 1 8 0 

时间复杂度: O(N^2)

空间复杂度: O(1)