How to sort an integer array into negative, zero, positive part without changing relative position?

前端 未结 5 1399
梦毁少年i
梦毁少年i 2021-02-04 08:31

Give an O(n) algorithm which takes as input an array S, then divides S into three sets: negatives, zeros, and positives. Show how to implement this in place, that is, without a

5条回答
  •  醉话见心
    2021-02-04 08:53

    Zeros are indistinguishable so I presume you don't care whether they get swapped around or even simply overwritten at the end (i.e. we just zero out the middle part after we've finished getting the positive and negative numbers moved to opposite ends of the array).

    If you're looking at a situation where the integers are just keys for something bigger, this may well not be the case- you may want zeros preserved and stably partitioned. But if not, here's two insights:

    First, your problem is identical to the stable binary partition problem.

    An algorithm for your problem of course does stable binary partitions (just an array with no zeros). Contrariwise, if the array has zeros you can still use a binary partition to do the dirty work: scan right through the array, swapping each zero you come across with the next negative value (keeping track of where that was so you don't do n^2 overall scanning), resulting in

    [mixed -,+][possibly extra zeros][mixed 0,+].

    Then you do two binary partitions to get

    [-][+][0][+]

    and shift the + values over to get the desired result.

    AFAIK with binary partitions you can choose any two of stable, in-place, and O(n). So it looks like you're outta luck, but apparently an in-place O(n*log n) algorithm is known as is an O(n) algorithm using log(n) scratch space.

    Second, if you can guarantee that the number of zeros will be at least f(n), the zeros can compensate for the lack of scratch space; it's simple to get a stable in-place partition in time O(n^2/f(n)). In particular, if the zeros will be at least some constant fraction of the array, you get O(n) runtime by just running these two steps till you're done:

    1. Scan right through the array, swapping each zero you come across with the next negative value
    2. Scan left through the array, swapping each zero you come across with the next positive value

    If zeros are just as plentiful as either of the other types, this is done after doing 1 then 2 then 1 again.

提交回复
热议问题