【问题标题】:Alternate positive and negative numbers in an array数组中交替的正数和负数
【发布时间】:2014-12-05 22:16:42
【问题描述】:

给定一个正负数数组(没有零),我必须以正负数应该连续排列的方式排列它们。

正数和负数的个数可能不相等,即如果没有剩余的正数(或负数),则将所有剩余的负数(或正数)附加到数组的末尾。

顺序很重要,即如果输入数组是{2,-1,-3,-7,-8, 9, 5,-5,-7},那么输出数组应该是{2,-1, 9,-3, 5,-7,-8,-5,-7}。代码在 O(n) 中完成,无需使用另一个数组。

这是我在java中的解决方案,我再次测试了几个案例,它可以工作。但是,我不确定这是否在 O(n) 时间内运行。基本上,我先数正数和负数的个数。然后我有两个索引i = 0j =1j 总是领先一步 i。从那里我继续检查i 中的数字是否为正,j 是否为负,如果不是,i 将遍历数组,直到找到正确位置的下一个正/负并移动它到正确的位置。

非常感谢任何建议。谢谢!

//array of negative and positive, arrange them so that positive number follow by negative
// if no pos or neg left, the rest append to the array. 
//should be O(n) no additional array
public static void alter(int[] a) {
    int pos = 0;
    int neg = 0;
    int index = 0;
    while (c < a.length) {
        if (a[index] > 0) {
            pos++;
        } else neg++;
        index++;
    }

    int i = 0;
    int j = 1;
    int temp = 0;
    //run until no more positive number or negative number
    while (pos > 0 && neg > 0) {
        //
        if (a[i] > 0) {
            pos--;
            if (a[j] < 0) {
                i += 2;
                j += 2;
                neg--;
            } else // a[j] > 0
            {
                while (a[j] > 0) {
                    j++;
                }
                //a[j] < 0
                neg--;
                //move that number to the appropriate place 
                while (j > i) {
                    temp = a[j];
                    a[j] = a[j - 1];
                    a[j - 1] = temp;
                    j--;
                } // end while
                i += 2;
                j += 2;
            }
        } else // a[i] < 0
        {
            while (a[i] < 0) {
                i++;
            }
            //a[i] > 0
            //move that number to the appropriate place 
            while (i > (j - 1)) {
                temp = a[i];
                a[i] = a[i - 1];
                a[i - 1] = temp;
                i--;
            }

        } //end else    
    }

}

【问题讨论】:

  • 你必须只有一个数组吗?因为至少有两个会更好
  • 是的,只允许一个数组

标签: java arrays


【解决方案1】:

但是,我不确定这是否在 O(n) 时间运行

我不认为它在O(n) 中运行。当您必须“找到下一个正确的元素并将其移动到正确的位置”时,您需要

  1. 循环遍历数组的其余部分。这意味着对于最坏的情况(开头所有正元素的数组,结束时所有负元素的数组),您将为每个正元素再循环一次超过数组“未排序”部分的一半
  2. 当您将元素移回正确位置时,您将逐个位置移动它。这意味着您再次循环遍历数组的“未排序”部分

如果您需要遵守在不使用第三个数组的情况下必须遵守排序的要求,那么您将如何在 O(n) 中运行它还不确定。

【讨论】:

    【解决方案2】:

    是的,可以在 O(n) 内完成。

    假设 c 是当前位置。 a[c] 是正数。

    1) 从 c 向数组末尾增加 i 直到 i 指向第一个错误数字(与前一个符号相同的数字) ,在这种情况下为正)。

    2)Set j := i;

    3) 向数组末尾增加 j 直到 j 指向带有所需符号的数字(在这种情况下为负数)。

    4) Swap a[i] with a[j].

    5)Set c := j;

    6)Set j := c + 1;

    在每一步中,您始终递增 ijc永不减少。 变量 i 的增量不能超过 n 次。与 jc 相同。

    所以最大增量是3n ~ O(n)

    【讨论】:

    • 我认为这不会保留订单。输入=[1,-1,2,-2,3,4,5,-3,6,-4,-5,-6];所需输出=[1,-1,2,-2,3,-3,4,-4,5,-5,6,-6];你的算法的输出: [1,-1,2,-2,3,-3,5,-4,6,-5,4,-6] 如果我正确理解了 OP 的问题。
    • 谢谢@ajb,你是对的。也许解决方案是:当 j 开始向右移动以寻找交换候选者时,算法应该将每个 a[j] 移动到 a[j+1] 并记住 temp 中的前一个 a[j+1]。当找到好的 a[j] 时,它被设置为空白的 a[c+1],并且由于在递增 j 时不断切换,因此排序不会中断。
    【解决方案3】:

    PFB 我的代码。如果我们将使用 Stack,那么它将使我们的问题更容易。

    public class AlternatePosNeg {
    public static void main(String[] args) {
        int arr[] = { 2, -1, -3, -7, -8, 9, 5, -5, -7 };
    
        Stack<Integer> pos = new Stack<>();
        Stack<Integer> neg = new Stack<>();
    
        int i;
    
        for (i = 0; i < arr.length; i++) {
            if (arr[i] > 0) {
                pos.push(arr[i]);
            } else {
                neg.push(arr[i]);
            }
        }
    
        int tempArr[] = new int[arr.length];
    
        i = 0;
    
        int sizePos = pos.size();
        int sizeNeg = neg.size();
    
        while (i < tempArr.length) {
            if (sizePos > sizeNeg) {
                if (pos.size() > 0) {
                    tempArr[i] = pos.pop();
                }
                if (neg.size() > 0) {
                    tempArr[i + 1] = neg.pop();
                    i++;
                }
            } else {
                if (neg.size() > 0) {
                    tempArr[i] = neg.pop();
                }
                if (pos.size() > 0) {
                    tempArr[i + 1] = pos.pop();
                    i++;
                }
            }
    
            i++;
        }
    
        for (int no : tempArr) {
            System.out.print(no + " ");
        }
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-31
      • 1970-01-01
      • 2016-02-14
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 2013-04-21
      相关资源
      最近更新 更多