【问题标题】:Arrange array of +ve and -ve number with order intact [duplicate]排列+ve和-ve数字的数组,顺序不变[重复]
【发布时间】:2012-07-05 04:15:33
【问题描述】:

可能重复:
which algorithm can do a stable in-place binary partition with only O(N) moves?

这是让我印象深刻的面试题之一

问题: 给定一个正负整数数组,您需要将正数移到一侧 和负数到另一边,订单完好无损。 前任。 {-1,5,3,-8,4,-6,9} 到 {-1,-8,-6,5,3,4,9}。这应该在 O(n) 中完成,并且不需要额外的数组。

首先我想通过像这样的快速排序来做到这一点

伪代码

找到最接近零的元素。使其成为枢轴元素。然后在数组上应用一次快速排序。这是 O(n) 。

唉!但是快速排序不是稳定排序?

之后我提出了以下解决方案

伪代码:

最初, 递增当前直到第一个 +ve 数字和递减结束直到最后一个 -ve 数字

如果电流为负,则增加电流 如果 current 为正,则将其与 end 的元素交换并减少 current 并结束两者 如果 current >= end ,则中断。

仍然没有得到正确的答案。需要这方面的建议

【问题讨论】:

  • 这不是一个解决方案,而是一个注意事项:复杂性约束(O(n),又名“线性”)是一个很大的提示。您不能使用快速排序,因为它平均 nlog(n) 并且在最坏的情况下是二次的。实际上,您不能使用任何具有类似要求的算法来比较元素,因为所有这些算法的复杂度都至少为 nlog(n)。您必须对元素进行排序,而无需将它们全部相互比较。 [顺便说一句,当我说“日志”时,它是 log-base-2。]
  • 我可能是错的,但也许他们只是想看看您如何解决问题而不是获得实际的解决方案? Radix Sort 最接近,但我认为没有任何实现同时就地稳定。对于只有一位数的数字数组,它也只是 O(n)。不过还是不错的。
  • @Jesse:我认为这不仅仅是相关的,这是一个骗局。或者你觉得有什么不同?
  • @BenVoigt:实际上,我没有。标记为骗子。

标签: c++ algorithm


【解决方案1】:

std::stable_partition 完全符合您的要求。

对于 C++11,执行

std::stable_partition(
  array.begin(), array.end(),
  [] (int i) { return i < 0; });

【讨论】:

  • 有趣。您知道该方法的基础是哪种算法吗? O(n)、就地和稳定的整数排序听起来很棘手
  • "复杂性:最多 (last - first) * log(last - first) 交换,但如果有足够的额外内存,则只有线性交换次数。确切地说是 last - first 谓词的应用程序。"
  • ...所以在最坏的情况下记录 n,然后不在原地。
  • @nbrooks:要么是O(n),要么是就地的,但不是两者兼而有之。
  • @ben 一般来说,如果你不能保证它在给定时间你不能真正将算法归类为那样,但我接受你在语言注释上的观点
【解决方案2】:

如果结果数组与源数组不同,您可以轻松完成两遍:

p = 0;   //current index in result array

For i = 0 to length - 1 :
    If source[i] < 0 then
        result[p] = source[i]
        increment p
    End if
End for

For i = 0 to length - 1 :
    If source[i] >= 0 then
        result[p] = source[i]
        increment p
    End if
End for

如果你想就地做,那就有点棘手了。您可以尝试冒泡排序,但这是 O(n^2):

n = 0  // number of negative items found

For i = 0 to length - 1 :
    If array[i] < 0 then
        For j = i - 1 downto n :
            swap array[j+1] and array[j]
        End for

        increment n
    End if
End for

不幸的是,我想不出一个既 O(n) 又不需要分配额外数组的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多