C++程序 在O(n)时间内并使用O(1)额外空间重新排列正负数

C++程序 在O(n)时间内并使用O(1)额外空间重新排列正负数

在日常生活和数学计算中,常常需要将一个数组中的正数和负数分别进行处理,例如将所有正数复制到另一个数组或者将所有负数取相反数。而有时候,需要重新排列这个数组,使得其左边为所有负数,右边为所有正数。那么如何用C++编写程序,在O(n)时间内并使用O(1)额外空间重新排列正负数呢?

通过观察题目,我们可以发现只要把数组中的正数和负数重新排列,其他元素的顺序并不改变。而解决这个问题的核心思想就是:使用双指针,分别从左右两端向中间扫描数组,将不符合要求的元素交换位置。

例如将数组int arr[] = {2, -4, 3, -1, -4, 0, 5, -6};重新排列后可以得到{-4, -1, -4, -6, 2, 3, 5, 0}。

以下是用C++实现该算法的代码:

#include <iostream>
using namespace std;

void reArrange(int arr[], int n)
{
    int left = 0;
    int right = n-1;

    while(left <= right){
        if(arr[left] < 0 && arr[right] < 0){
            // 左侧是负数,右侧也是负数,则交换
            swap(arr[left], arr[right]);
            left++;
        }else if(arr[left] > 0 && arr[right] < 0){
            // 左侧是正数,右侧是负数,则交换
            swap(arr[left], arr[right]);
            left++;
            right--;
        }else if(arr[left] > 0 && arr[right] > 0){
            // 左侧是正数,右侧也是正数,则不需要交换
            right--;
        }else{
            // 左侧是负数,右侧是正数,则不需要交换
            left++;
            right--;
        }
    }
}

int main()
{
    int n = 8;
    int arr[] = {2, -4, 3, -1, -4, 0, 5, -6};

    reArrange(arr, n);

    for(int i = 0; i < n; i++)
        cout<<arr[i]<<" ";

    return 0;
}

代码说明:

  • 函数 reArrange(int arr[], int n) 用于重新排列数组arr。其中,数组长度为n。
  • 双指针left和right分别从左右两端向中间扫描数组。
  • 当left指向的元素为负数且right指向的元素为负数时,左指针右移,继续扫描。
  • 当left指向的元素为正数且right指向的元素为负数时,将两个元素交换,left指针右移,right指针左移。
  • 当left指向的元素为正数且right指向的元素为正数时,右指针左移,继续扫描。
  • 当left指向的元素为负数且right指向的元素为正数时,left指针右移,right指针左移,继续扫描。

解决方案

此算法分为三个步骤:

  1. 初始化指向数组左端和右端的两个指针(left和right)。
  2. 循环遍历数组,将left和right指针都往中间移动,直到left大于等于right,遍历结束。
  3. 在遍历的过程中,通过观察left指针和right指针当前指向的元素,让指针执行合适的操作。根据题目要求,我们需要将数组中的负数排在左边,正数排在右边。因此,我们有以下四种情况:
  • 如果left指向的元素是负数,right指向的元素也是负数,那么left指针右移,直到找到一个正数或者left大于等于right。
  • 如果left指向的元素是正数,right指向的元素是负数,那么left和right指针都要执行交换操作,然后left指针右移,right指针左移。
  • 如果left指向的元素是正数,right指向的元素也是正数,那么right指针左移,直到找到一个负数或者left大于等于right。
  • 如果left指向的元素是负数,right指向的元素是正数,那么left指针右移,right指针左移,直到指向元素为第二种情况。

在上面的示例代码中,我们用了 swap() 函数来交换 left 和 right 指针所指向的元素。具体地,如果元素 a 和元素 b 需要交换,则可以使用以下代码:

swap(a, b);

此函数的返回值为空,因为它只是简单地交换了两个元素的值。由于 swap() 函数是 C++ STL 中的函数,在程序中需要添加头文件 #include ,才能正确运行。

至此,我们已经解决了如何在O(n)时间内并使用O(1)额外空间重新排列正负数的问题。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程

C++ 示例