在不使用多个数据结构的情况下,在O(n)时间内阵列一侧的负数

时间:2016-09-29 12:50:54

标签: arrays algorithm data-structures

我们不能使用多个DS。 时间复杂度O(n)。

目标:左侧的所有负面元素和右侧的正面元素。

请不要排序。

我正在尝试这个,但不知道这里有什么问题。

请帮帮忙!

我很确定所有案件都会得到照顾!

        #include <iostream>

        using namespace std;

          int main(void){

           int arr[100], n, temp=0;

          cout << "Enter the size of array";
          cin >> n;

          for(int i=0; i<n; i++){

             cout << "Enter elements of array";
             cin >> arr[i];

          }

               int j=0;

            for(int k=n-1; k>=j; k--) {

    if(arr[j]<0 && arr[k]>=0) {

            j++;
    }

            if(arr[j]>=0 && arr[k]<0) {

                    temp = arr[k];
                    arr[k] = arr[j];
                    arr[j] = temp;
                    j++;
            }

                    if(arr[j]<0 && arr[k]<0) {

                            j++;
                            k++;

                    }

                            if(arr[j]>=0 && arr[k]>=0) {

                                    continue;

                            }

              }

            cout << arr;

             }

1 个答案:

答案 0 :(得分:1)

你不能用零做出你想做的事情;假设零被忽略,它们的位置并不重要。如果零被视为正面或负面,或者它们应该出现在中间而不是任意位置,下面的一些细节将需要调整,但这将使你基本上得到你想去的地方。

  1. 从左侧开始,向右扫描,找到第一个正数。我们将其基于零的索引i称为。如果未找到正数,则终止算法。
  2. 从右侧开始,向左扫描,找到第一个负数。我们将其基于零的索引j称为。如果未找到负数,则终止算法。
  3. Iff i < j,交换索引ij的元素,并递归地解决从i+1j-1的数组切片的相同问题,包含(如果i+1 >= j-1,您可以简单地终止)。
  4. 这可以保证正确解决您的问题。证明是通过对数组长度的数学归纳。

    基本情况:空数组和长度为1的数组已经满足所需的属性,不需要交换。该算法会查看此类数组,并且不执行任何操作。

    归纳假设:假设算法正确处理了最多k个元素的所有数组;也就是说,算法将所有负元素向左移动,所有正元素向右移动。

    归纳步骤:我们必须证明算法正确处理长度为k+1的数组。假设k+1元素数组已满足该属性。我们的算法查看所有元素并且什么都不做。相反,假设至少有一个元素不合适。这意味着有一个正数,右边有一个负数。特别是,在其右侧有一个最左边的正数,负数。同样,最右边的负数在其左边有一个正数。我们的算法交换这两个数字,创建一个数组,这些数字不再是不合适的。由于我们假设最左边和最右边的正数和负数,任何其他掉期必须出现在我们刚刚交换的数字内。我们的算法处理数组的这一部分,其大小最多为k+1-2 = k-1,根据假设,我们的算法正确处理。 QED

    迭代实现的伪代码:

    i = 0
    j = n-1
    while i < j do
        while !(array[i] > 0) do
            i = i + 1
        while !(array[j] < 0) do
            j = j - 1
        if i < j then
            tmp = array[i]
            array[i] = array[j]
            array[j] = tmp
    

    如果您想将零视为否定,请将array[j] < 0更改为array[j] <= 0。如果您想将零视为正数,请将array[i] > 0更改为array[i] >= 0。如果你想在中间使用零,那么运行上面的伪代码三次:一次交换负数和正数,一次交换负数和零,一次交换正数和零。