给定一组正负整数,重新排列它,使得一端为正整数,另一端为负整数。

时间:2011-02-04 11:04:16

标签: arrays algorithm sorting

我最近遇到了面向软件工程师的Microsoft面试问题。

给定一组正负整数,重新排列它,使得一端为正整数,另一端为负整数,但保留原始数组中的出现顺序。 < / p>

例如,给定[1, 7, -5, 9, -12, 15]
答案是:[-5, -12, 1, 7, 9, 15]

这应该在O(n)中完成。

我们可以很容易地在O(n)中完成它,但我无法想象我们如何能够像原始数组一样维护元素的顺序。如果我们忘记O(n)复杂性,有人可以告诉我如何在不考虑空间和时间复杂性的情况下保持元素的顺序。

编辑:在实际问题中,我们还要求O(1)空间复杂度。

29 个答案:

答案 0 :(得分:13)

要在恒定空间(但是二次时间)内实现此结果,可以通过在数组的每一端放置一个队列来使用双队列方法(类似于荷兰国旗算法)。从左到右读取项目:向左侧队列添加项目意味着不管它,将项目添加到右侧队列意味着将不在队列中的所有元素向左移动一个并将添加的项目放在最后。然后,要连接队列,只需反转第二个队列中元素的顺序。

执行O(n)操作(向左移位元件)直到O(n)次,这产生O(n²)运行时间。

通过使用类似于合并排序的方法,可以实现更低的O(n log n)复杂度:将数组分成两半,以[N P] [N P]的形式递归排序,然后交换第一个{{1在O(n)时间内使用第二个P(当它们没有完全相同的大小时它会变得有点棘手,但它仍然是线性的)。

我完全不知道如何将其缩短到O(n)时间。

编辑:实际上,您的链接列表是正确的。如果数据是作为双向链表提供的,则可以在O(n)时间内实现双队列策略,O(1)空间:

N

使用链表实现来保持指向第一个和最后一个元素的指针,然后pop,append和concatenate都是O(1)操作,因此总复杂度为O(n)。至于空间,没有任何操作分配任何内存(追加只使用pop发布的内存),所以它总是O(1)。

答案 1 :(得分:9)

这是O(n)时间O(1)空间解的一个constriant版本,它假设maxValue *(maxValue + 1)小于Integer.MAX_VALUE,其中maxValue是maxmum值减去minmum值的结果阵列。它利用原始数组作为临时数组来存储结果。

public static void specialSort(int[] A){
    int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
    for(int i=0; i<A.length; i++){
        if(A[i] > max)
            max = A[i];
        if(A[i] < min)
            min = A[i];
    }
    //Change all values to Positive
    for(int i=0; i<A.length; i++)
        A[i]-= min;

    int newMax = max-min+1;

    //Save original negative values into new positions
    int currNegativeIndex = 0;
    for(int i=0; i<A.length; i++)
        if(A[i]%newMax < (-min))
            A[currNegativeIndex++] += (A[i]%newMax)*newMax;
    //Save original positive values into new positions
    int currPositiveIndex = currNegativeIndex;
    for(int i=0; i<A.length; i++)
        if(A[i]%newMax > (-min))
            A[currPositiveIndex++] += (A[i]%newMax)*newMax;
    //Recover to original value 
    for(int i=0; i<A.length; i++){
        A[i] = A[i]/newMax + min; 
    }
}

答案 2 :(得分:6)

我不确定我是否正确理解了这个问题,因为答案看起来太简单了:

  • 遍历数组并计算负数 - O(n)
  • 创建一个大小为O(n)
  • 的新数组
  • 浏览原始数组并将数字放入新数组中。使用已知数量的负数来抵消正数 - O(n)

这是在Python中快速完成此操作的方法。它与上面略有不同,首先为负片创建一个数组,然后附加正数。所以它不那么有效,但仍然是O(n)。

>>> a = [1,7,-5,9,-12,15]
>>> print [x for x in a if x < 0] + [y for y in a if y >= 0]
[-5, -12, 1, 7, 9, 15]

编辑:好的,现在有了O(1)空间复杂性,它变得更加困难。我对如何在O(n)时间复杂度中实现它感兴趣。如果它有帮助,这是一种保持O(1)空间复杂度的方法,但需要O(n ^ 2)时间复杂度:

  • 从最左边的负数开始。遍历阵列,直到找到下一个负数。
  • 在新循环中,将负数与其左侧的正数进行交换。这样做直到你到达其他负数。这可以确保数字的顺序保持不变。
  • Rince并重复,直到找到新的负数时到达阵列的末尾。

答案 3 :(得分:5)

可以在O(n)和空间O(1)中完成。

我们需要在数组中扫描3次并仔细更改一些值。

假设:大小为N的数组中的最大值应小于(N+1) * Integer.MAX_VALUE

我们需要这个假设,因为我们很好地改变了数组中的一些正值。

  • 在第一次扫描中,找到负值和正值的#,以及最大值
  • 在第二次扫描中,我们按如下方式创建数组的负数部分:

我们从数组的开头开始,我们&#34; 交换&#34;第一个找到正数(例如在索引i),第一个找到负数(例如j)。由于负数正在考虑其位置,因此交换是可以的。

问题是正数,因为ij之间可能还有其他一些正数。为了解决这个问题,我们必须在交换之前以某种方式编码该值中正数的索引。那么我们就可以意识到它在第一点的位置。我们可以通过a[i]=(i+1)*(max)+a[i]完成此操作。

  • 在第三次扫描中,我们创建了数组的正部分。在第二次扫描结束时,构造负数组,并且正数移位到右侧,但它们的位置可能不正确。因此,我们通过它并纠正他们的位置,因为这些信息被编码了它们的价值。

以下是代码:

import java.util.Arrays;

public class LinearShifting {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] a = {-1,7,3,-5,4,-3,1,2};
        sort(a);
        System.out.println(Arrays.toString(a));  //output: [-1, -5, -3, 7, 3, 4, 1, 2]
    }
    public static void sort(int[] a){
        int pos = 0;
        int neg = 0;
        int i,j;
        int max = Integer.MIN_VALUE;
        for(i=0; i<a.length; i++){
            if(a[i]<0) neg++;
            else pos++;
            if(a[i]>max) max = a[i];
        }
        max++;
        if(neg==0 || pos == 0) return;//already sorted
        i=0;
        j=1;
        while(true){
            while(i<=neg && a[i]<0) i++;
            while(j<a.length && a[j]>=0) j++;
            if(i>neg || j>=a.length) break;
            a[i]+= max*(i+1);
            swap(a,i,j);
        }

        i = a.length-1;
        while(i>=neg){
            int div = a[i]/max;
            if(div == 0) i--;
            else{
                a[i]%=max;
                swap(a,i,neg+div-2);// minus 2 since a[i]+= max*(i+1);
            }
        }

    }
    private static void swap(int[] a, int i , int j){
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

}

答案 4 :(得分:3)

编辑(2015年5月29日):我忽略了维持外观顺序的要求,因此下面的答案不能满足问题的所有要求。但是,为了普遍的兴趣,我保留原来的回复。


这是一个非常重要的快速排序子程序的特殊版本,称为“分区”。定义:如果A [i] <1,则具有N个数字条目的数组A在索引p处被分割为值K. K为0&lt; = i&lt; p和A [j]> = K,p&lt; = j&lt; N,除非所有条目都小于K(意味着p = N)或不小于K(意味着p = 0)。对于有问题的问题,我们将在K = 0附近对数组进行分区。

您可以在O(n)时间内对未排序的数组中的任何值K进行分区,只需使用O(1)附加内存访问数组中的每个条目一次。非正式地,您从两端逐步遍历数组,移动错误的值。当在阵列的每一侧发现一个错位值,然后继续向内踩时,执行交换。现在是C ++代码:

// Assume array A[] has size N
int K = 0; // For particular example partitioning positive and negative numbers
int i = 0, j = N-1; // position markers, start at first and last entries
while(1) { // Break condition inside loop
    while(i < N && A[i] < K) i++; // Increase i until A[i] >= K
    while(j >= 0 && A[j] >= K) j--; // Decrease j until A[j] < K
    if(i < j) 
        swap(A[i],A[j]);
    else
        break;
}
// A[] is now partitioned, A[0]...A[j] < K, unless i==0 (meaning all entries >= K).

注意,如果所有元素都等于K(在这种情况下为零),则i永远不会递增,并且j = 0。问题陈述假定这种情况永远不会发生。分区非常快速有效,这种效率是quicksort成为大型阵列最常用的排序例程的原因。交换函数可以是C ++中的std :: swap,也可以轻松编写自己的函数:

void swap(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}

或者只是为了好玩,数字可以在没有临时内存的情况下交换,但要注意溢出:

// This code swaps a and b with no extra space.  Watch out for overflow!
a -= b;
b += a;
a = b - a;

对于特殊情况,分区有许多变体,例如[elements&lt; K] [elements == K] [elements&gt; K]。快速排序算法递归地调用分区,并且分区值K通常是当前子阵列中的第一个条目或者从几个条目(例如三个中值)计算。参见教科书:Sedgewick和Wayne的算法(第4版,第288页)或计算机程序设计艺术卷。 3由Knuth撰写(第2版,第113页)。

答案 5 :(得分:2)

您可以使用2个队列并合并它们。这样,您只需在第一个数组和每个子队列上迭代一次。

negatives = []
positives = []

for elem in array:
  if elem >= 0:
    positives.push(elem)
  else
    negatives.push(elem)

result = array(negatives, positives)

答案 6 :(得分:2)

这是一个只有2次迭代的解决方案:
假设长度为n。
我将使用C代码,忽略语法错误。

solution[n];
for (i= 0,j=0 ; i < n ; i++ ) {
     if (array[i] < 0) solution[j++] = array[i];
}
for (i = n-1,j=n-1 ; ; i > 0 ; i--) {
     if (array[i] >= 0) solution[j--] = array[i];
}

我的想法是重复一次,并写下我们遇到的所有负面因素 然后从结尾第二次过去,并从结尾写到正面。

答案 7 :(得分:2)

该解决方案具有O(n)时间复杂度和O(1)空间复杂度

想法是:

  1. 跟踪上次看到的负面元素的索引(lastNegIndex)。

  2. 遍历数组以查找前面带有正元素的负面元素。

  3. 如果找到此元素,则将lastNegIndex和当前Index之间的元素右移一个。然后更新lastNegIndex(它将是下一个索引)。

  4. 以下是代码:

    public void rightRotate(int[] a, int n, int currentIndex, int lastNegIndex){
        int temp = a[currentIndex];
        for(int i = currentIndex; i > lastNegIndex+ 1; i--){
            a[i] = a[i-1];
        }
        a[lastNegIndex+1] = temp;
    }
    
    public void ReArrange(int[] a, int n){
        int lastNegIndex= -1;
        int index;
    
        if(a[0] < 0)
            lastNegIndex = 0;
    
        for(index = 1; index < n; index++){
             if (a[index] < 0 && a[index - 1] >= 0) {
                 rightRotate(a, n, index, lastNegIndex);
                 lastNegIndex = lastNegIndex + 1;
             }
        }
    }
    

答案 8 :(得分:1)

我非常怀疑O(n)时间和O(1)是否可行 数组 。有些建议链接列表,但您需要一个自定义链接列表,您可以直接访问节点来执行此操作,即。语言内置链表不起作用。

我的想法是使用自定义双重链接列表来满足约束的复杂性,使用[1,7,-5,9,-12,15]作为例如:

在列表中循环,如果看到否定,请将其剪切并将其添加到前面底片的末尾。每个操作都是O(1),因此总时间为O(n)。链接列表操作就位,因此O(1)空间。

详细说明:

last_negative_node = null;

at -5: 

cut off -5 by setting 7.next = 9, 

then add -5 to front by -5.next = 1, 

then update last_negative_node = 5 // O(1), the linked list is now [-5, 1, 7, 9, -12, 15]


at -12: 

cut off -12 by setting 9.next = 15, 

then add -12 to front by -12.next = last_negative_node.next, 

then update last_negative_node.next = -12,

then update last_negative_node = -12 //O(1), the linked list is now [-5, -12, 1, 7, 9, 15]

no more negatives so done.

答案 9 :(得分:1)

以下是qiwangcs's solution的JavaScript实现:

function specialSort(A){
    let min = Number.MAX_SAFE_INTEGER, max = -Number.MAX_SAFE_INTEGER;
    for(let i=0; i<A.length; i++){
        if(A[i] > max)
            max = A[i];
        if(A[i] < min)
            min = A[i];
    }
    //Change all values to Positive
    for(let i=0; i<A.length; i++)
        A[i]-= min;
    const newMax = max-min+1;        
    //Save original negative values into new positions
    let currNegativeIndex = 0;
    for(let i=0; i<A.length; i++)
        if(A[i]%newMax < (-min))
            A[currNegativeIndex++] += (A[i]%newMax)*newMax;
    //Save original positive values into new positions
    let currPositiveIndex = currNegativeIndex;
    for(let i=0; i<A.length; i++)
        if(A[i]%newMax > (-min))
            A[currPositiveIndex++] += (A[i]%newMax)*newMax;
    //Recover to original value 
    for(let i=0; i<A.length; i++){
        A[i] = Math.floor(A[i]/newMax) + min; 
    }
}
// Demo
const A = [-3,-7,2,8,-5,-2,4];
specialSort(A);
console.log(A);

答案 10 :(得分:1)

O(n)解决方案Java

    private static void rearrange(int[] arr) {
    int pos=0,end_pos=-1;
    for (int i=0;i<=arr.length-1;i++){  
        end_pos=i;
        if (arr[i] <=0){
            int temp_ptr=end_pos-1;
            while(end_pos>pos){
                int temp = arr[end_pos];
                arr[end_pos]=arr[temp_ptr];
                arr[temp_ptr]=temp;
                end_pos--;
                temp_ptr--;
            }
            pos++;
        }

    }

答案 11 :(得分:1)

如果开头的结构不一定是数组,那就更简单了。

如果您在链接列表中包含原始数字,则很容易。

您可以重新排列链接列表,只是每次指向下一个负数旁边的负数,下一个正数旁边的正数。

再次C代码,忽略语法。 (可能需要在这里和那里进行空检查,但这是个主意)

Cell firstPositive;
Cell* lastPoisitive;
lastPoisitive = &firstPositive;
Cell firstNegative;
Cell* lastNegative;
lastNegative = &firstNegative;
Cell* iterator;
for(Iterator = list.first ; Iterator != null ; Iterator = Iterator->next) {
   if (Iterator->value > 0 ) lastPoisitive->next = Iterator;
   else lastPoisitive->next = Iterator;
}
list.first = firstNegative->next;
list.last.next = firstPositive->next;

答案 12 :(得分:1)

如果目标是O(1)空间(除了元素本身,假设是可自由变化的)和O(NlgN)时间,则将问题划分为安排已知为pnPN形式的数组的问题其中p和P表示零个或多个正数,n和N表示0或更多个负数,形成pPnN形式的阵列。任何双元素数组都将自动成为该形式。给定该形式的两个数组,找到第一个负数,下一个正数和最后一个正数,并“旋转”数组的中间两个部分(在常量空间中容易做,并且时间与数组的大小成比例)被'旋转')。结果将是pPnN形式的数组。两个连续的这样的数组将形成一个更大的形式pnPN。

要在恒定空间中做事,首先将所有元素配对并将它们放入PN形式。然后执行所有四元组元素,然后是所有八位字节等,直到数组的总大小。

答案 13 :(得分:1)

只是一个想法..让我们考虑一个更简单的问题:

给定一个数组,其中第一部分(Np元素)仅包含正数,最后一部分(Nn元素):仅包含负数。 如何在维持相对顺序的同时交换这些部分?

最简单的解决方案是使用反转:

inverse(array, Np + Nn); // whole array
inverse(array, Nn);      // first part
inverse(array+Nn, Np);   // second part

它具有O(n)时间复杂度和O(1)空间复杂度。

答案 14 :(得分:0)

int [] input = {1, 7, -5, 9, -12, 15};
int [] output = new int [input.length];
int negativeIdx = 0;
int positiveIdx = input.length - 1;
for(int i = 0; i < input.length ; i++) {
    if(input[i] < 0) {
        output [negativeIdx++] = input[i];
    } else {
        output [positiveIdx--] = input[i];
    }
}
System.out.println

(Arrays.toString(output));

输出:

[-5, -12, 15, 9, 7, 1]

答案 15 :(得分:0)

这使用QuickSort的分区过程。该解决方案的时间复杂度为O(n2),辅助空间为O(1)。这种方法保持了外观的顺序,并没有使用任何其他数据结构。这是Ruby

def sortSeg(intArr)
    intArr.each_with_index do |el, idx|
        # if current element is pos do nothing if negative,
        # shift positive elements of arr[0..i-1],
        # to one position to their right */
        if el < 0
            jdx = idx - 1;
            while (jdx >= 0 and intArr[jdx] > 0)
                intArr[jdx + 1] = intArr[jdx];
                jdx = jdx - 1;
            end
            # Insert negative element at its right position
            intArr[jdx + 1] = el;
        end
    end
end

答案 16 :(得分:0)

我认为这样可行:这是一个简单的方法,它是恒定的空间(但是是二次时间)。假设数组是长度N.沿着数组从i = 0到i = N-2检查元素i和i + 1。如果元素i为正数且元素i + 1为负数,则交换它们。然后重复这个过程。

每次越过数组都会使负数向左漂移(正向漂移到右侧),有点像气泡排序,直到(经过足够次数的传递后)它们都在正确的位置。

另外,我认为这样可行:它也是恒定的空间(但是是二次时间)。说P是正数的数量。当您发现正x停止扫描时,从左向右扫描,并通过将所有项目向左移动后将其“删除”。然后将x放在数组的末尾。重复步骤扫描P次以移动每个阳性。

答案 17 :(得分:0)

此代码使用O(n)复杂度和O(1)空间。 无需声明另一个数组。

#include <stdio.h>

int* sort(int arr[], int size)
{
    int i;
    int countNeg = 0;
    int pos = 0;
    int neg = 0;

    for (i = 0; i < size; i++)
    {
        if (arr[i] < 0)
            pos++;
    }

    while ((pos < (size-1)) || (neg < size-(pos-1)))
    {
        if ((arr[pos] < 0) && (arr[neg] > 0))
        {
            arr[pos] = arr[pos] + arr[neg];
            arr[neg] = arr[pos] - arr[neg];
            arr[pos] = arr[pos] - arr[neg];
            pos++;
            neg++;
            continue;
        }
        if ((arr[pos] < 0) && (arr[neg] < 0))
        {
            neg++;
            continue;
        }
        if ((arr[pos] > 0) && (arr[neg] > 0))
        {
            pos++;
            continue;

        }
        if ((arr[pos] > 0) && (arr[neg] < 0))
        {
            pos++;
            neg++;
            continue;

        }
    }
    return arr;
}

void main()
{
    int arr[] = { 1, 7, -5, 9, -12, 15 };
    int size = sizeof(arr) / sizeof(arr[0]);
    sort(arr, size);
    int i;
    for (i = 0; i < size; i++)
    {
        printf("%d ,", arr[i]);
    }
    printf(" \n\n");
}

答案 18 :(得分:0)

#include <iostream>

using namespace std;

void negativeFirst_advanced (int arr[ ], int size)

{

    int count1 =0, count2 =0;

    while(count2<size && count1<size)
{

        if(arr[count1]>0 && arr[count2]<0)
        {       
            int temp = arr[count1];
            arr[count1] = arr[count2];
            arr[count2] = temp;
        }

        if (arr[count1]<0)
            count1++;
        if (arr [count2]>0)
            count2++;

    }
}

int main()
{

        int arr[6] = {1,7,-5,9,-12,15};
        negativeFirst_advanced (arr, 6);
        cout<<"[";
        for (int i =0; i<6;i++)
            cout<<arr[i]<<" , ";
        cout<<"]";

        system("pause");
        return 0;
}

答案 19 :(得分:0)

这是我在 Python 中的解决方案,使用递归(我有一个这样的赋值,其中数组应该相对于数字K进行排序。如果你把K = 0,你&#39;得到了你的解决方案,没有保留外观顺序):

def kPart(s, k):
    if len(s) == 1:
        return s
    else:
        if s[0] > k:
            return kPart(s[1:], k) + [s[0]]
        else:
            return [s[0]] + kPart(s[1:], k)

答案 20 :(得分:0)

首先,计算负数元素的数量k。 然后,您知道数组的第一个k数字(数组的第一部分)应为负数。 排序数组后,以下N - k元素应为正数。

您维护两个计数器,表示在数组的两个部分中有多少元素遵守这些条件,并在每一步增加它,直到您知道一个部分是正常的(计数器等于该部分的大小)。那么另一部分也可以。

这需要O(1)存储并花费O(N)时间。

用C ++实现:

#include <iostream>
#include <vector>

using namespace std;

void swap(vector<int>& L, int i, int j) {
    int tmp = L[i];
    L[i] = L[j];
    L[j] = tmp;
}

void signSort(vector<int>& L) {
    int cntNeg = 0, i = 0, j = 0;
    for (vector<int>::iterator it = L.begin(); it < L.end(); ++it) {
        if (*it < 0) ++cntNeg;
    }
    while (i < cntNeg && cntNeg + j < L.size()) {
        if (L[i] >= 0) {
            swap(L, i, cntNeg + j);
            ++j;
        } else {
            ++i;
        }
    }
}

int main(int argc, char **argv) {
    vector<int> L;
    L.push_back(-1);
    L.push_back(1);
    L.push_back(3);
    L.push_back(-2);
    L.push_back(2);
    signSort(L);
    for (vector<int>::iterator it = L.begin(); it != L.end(); ++it) {
        cout << *it << endl;
    }
    return 0;
}

答案 21 :(得分:0)

下面是一个非常简单的解决方案,但不是O(n)。我稍微更改了插入排序算法。它不是检查数字是大于还是小,而是检查它们是大于还是小于零。

 int main() {

    int arr[] = {1,-2,3,4,-5,1,-9,2};

        int j,temp,size;

        size = 8;
        for (int i = 0; i <size ; i++){
            j = i;  
            //Positive left, negative right
            //To get opposite, change it to: (arr[j] < 0) && (arr[j-1] > 0)
            while ((j > 0) && (arr[j] >0) && (arr[j-1] < 0)){
                  temp = arr[j];
                  arr[j] = arr[j-1];
                  arr[j-1] = temp;
                  j--;
            }
        }

        //Printing
        for(int i=0;i<size;i++){
            cout<<arr[i]<<" ";      
        }
        return 0;
 }

答案 22 :(得分:0)

这是不是复杂性O(1),而是一种更简单的方法。做评论

void divide (int *arr, int len) {
    int positive_entry_seen = 0;                                                                                             
    for (int j = 0; j < len ; j++) { 
        if (arr[j] >= 0 ) { 
            positive_entry_seen = 1;
        } else if ((arr[j] < 0 ) && positive_entry_seen) {
            int t = arr[j];
            int c = j;
            while ((c >= 1) && (arr[c-1] >= 0)) {
                arr[c] = arr[c-1];
                c--;
            }   
            arr[c] = t;
        }   
    }   
}

答案 23 :(得分:-1)

我尝试过使用冒泡排序方法,它完美无缺,并且在原始数组中保留了它们的外观顺序。

&#13;
&#13;
int main()
{
    int array[TAM], num, i=0, j=0;

    printf("Ingrese arreglo: ");

    for(i=0; i < TAM -1 && num != 0; i++)
    {
        scanf("%d", &num);
        array[i]=num;
    }

    for(i=0; array[i] != 0 ; i++)
    {
        j++;
    }

    Alternar(array, j);

    //MOSTRAR
    for(i=0; i < j; i++)
    {
        printf("%d ", array[i]);
    }


    return 0;
}

void Alternar(int array[], int j)
{
    int i=0, aux, pasadas=1;

    for(pasadas=1; pasadas < j; pasadas++)
    {
        for(i=0; i < j - pasadas ; i++)
        {
            if(array[i] > 0 && array[i+1] < 0)
            {
                aux = array[i];
                array[i] = array[i+1];
                array[i+1] = aux;
            }
        }
    }

}
&#13;
&#13;
&#13;

答案 24 :(得分:-1)

这里我的回答是单个数组中的两个单独的正负值,它会帮助你

int[] singleArray= {300, -310, 320, 340, 350,
                -330, 420, 370, -360, 390,
                340, -430, 320, -463, 450}; 
public double[] getPositive_SingleArray() {
            double minValue = 0;
            double positiveValue=0;
            int count=0;
            for (int i = 0; i < singleArrayData.length; i++) {
                if ( singleArrayData[i]>0)
                    count++;
            }
            positiveSingleArrayData=new double[count];
            int k=0;
            for (int i = 0; i < singleArrayData.length; i++) {
                if ( singleArrayData[i]>0){
                positiveSingleArrayData[k] = singleArrayData[i];
                k++;
                }
             }
            System.out.println("single array of positve values "+Arrays.toString(positiveSingleArrayData));
            return positiveSingleArrayData;
        }

答案 25 :(得分:-1)

这可以简单地通过遵循O(n)中的步骤来完成,而不使用任何额外的空间

int count = 0;
//data is the array/vector in sort container having given input.
if(data[0] < 0)
    count++;
for(int i = 1; i < n; i++)
{
    if(data[i] < 0)
    {
        int j = i;
        while(j> count)
        {
            data[j-1] += data[j];
            data[j] = (data[j-1]-data[j]);
            data[j-1] -= data[j];
            j--;
        }
        count++;
    }
}

完整的实施可以在https://gist.github.com/Shravan40/8659568

找到

答案 26 :(得分:-1)

我希望这会有所帮助。这个有时间复杂度O(n ^ 2)

#include <stdio.h>

int main() {
    int a[] = {-3, 2, -5, 9, -2, -8, 6, 8, -1, 6};

    int length = (sizeof(a) / sizeof(int));
    int i, j = 0;

    printf("Size of array: %d\n", sizeof(a));

    for (i = 0; i < length; i++) {
        if (i % 2 == 0 && a[i] < 0) {
            for (j = i + 1; j < length; j++) {
                if (a[j] > 0) {
                    int t = a[i];
                    a[i] = a[j];
                    a[j] = t;
                    break;
                }
            }
        } else if (i % 2 == 1 && a[i] > 0) {
            for (j = i + 1; j < length; j++) {
                if (a[j] < 0) {
                    int t = a[i];
                    a[i] = a[j];
                    a[j] = t;
                    break;
                }
            }
        }
    }

    for (i = 0; i < length; i++) {
        printf("Value at %d: %d\n", i, a[i]);
    }

    return 0;
}

编辑1 这取决于大于零的数字始终为偶数索引而小于零的数字始终为奇数索引的事实

编辑2 改进了一点代码

答案 27 :(得分:-1)

我对数组的值进行了硬编码。但是它可以使用任何整数集。

    int[] n={2,-3,1,5,-10,-8};
    int k=0;
    for(int i=1;i<n.length;i++)
    {
        int temp=0;
        if(n[i]<0)
        {
            temp=n[k];
            n[k]=n[i];
            n[i]=temp;
            k++;
        }
    }

        for(int j=0;j<n.length;j++)
    {
        System.out.println(n[j]);
    }

答案 28 :(得分:-3)

在维基百科的排序算法表中查看Heapsort: http://en.wikipedia.org/wiki/Sorting_algorithm