【问题标题】:Arrays: Find minimum number of swaps to make bitonicity of array minimum?数组:找到最小交换次数以使数组的双调性最小?
【发布时间】:2017-12-20 03:28:44
【问题描述】:

假设给定一个整数数组。所有相邻的元素都保证是不同的。让我们使用以下关系将这个数组 abitonicity 定义为 bt

bt_array[i] = 0, if i == 0;
            = bt_array[i-1] + 1, if a[i] > a[i-1]
            = bt_array[i-1] - 1, if a[i] < a[i-1]
            = bt_array[i-1], if a[i] == a[i-1]

bt = last item in bt_array

我们说一个数组的双调性是最小,当它的双调性为0时,如果它有奇数个元素,或者它的双调性是+1或-1,如果它有偶数个元素.

问题是要设计一种算法来找到最少的交换次数,以使任何数组的双调性最小。该算法的时间复杂度最差应该是 O(n),n 是数组中元素的数量。

例如,假设a = {34,8,10,3,2,80,30,33,1}

它的初始bt 是-2。最小值为 0。这可以通过 1 次交换来实现,即交换 2 和 3。所以输出应该是 1。

这里有一些测试用例:

测试用例 1:a = {34,8,10,3,2,80,30,33,1},最小交换次数 = 1(交换 2 和 3)

测试用例 2:{1,2,3,4,5,6,7}:min swaps = 2(将 7 与 4 交换,将 6 与 5 交换)

测试用例 3:{10,3,15,7,9,11}:min swaps = 0。bt = 1。

还有一些:

{2,5,7,9,5,7,1}:当前bt = 2。交换 5 和 7:minSwaps = 1

{1,7,8,9,10,13,11}:当前bt = 4:交换 1,8:minSwaps = 1

{13,12,11,10,9,8,7,6,5,4,3,2,1}:当前bt = -12:交换 (1,6),(2,5 ) 和 (3,4) : minSwaps = 3


我在一次采访中被问到这个问题,这是我想出的:

1. Sort the given array.
2. Reverse the array from n/2 to n-1.
3. Compare from the original array how many elements changed their position. 
   Return half of it.

还有我的一些代码:

int returnMinSwaps(int[] a){
    int[] a = {1,2,3,4,5,6,7};
    int[] b = a;
    Arrays.sort(b);
    for(int i=0; i<= b.length/2 - 1; i++){
        swap(b[b.length - i], b[b.length/2 - i]);
    }
    int minSwaps = 0;
    for(int i=0;i<b.length;i++){
        if(a[i] != b[i])
            minSwaps++;
    }
    return minSwaps/2;
}

不幸的是,对于使用此逻辑的某些测试用例,我没有得到正确的最小方法数。另外,我正在对O(n log n) 中的数组进行排序,并且需要在O(n) 中完成。

【问题讨论】:

  • @VidorVistrom:所有元素都是不同的。但在我看来,我想你想问两个相邻的元素是否不同,对吧?所有相邻的元素都是不同的。让我也将其放入编辑中。感谢您指出。
  • @YakymPirozhenko 交替排列只是双调数组的一种特殊情况。它可以是{+, -, +, -, ...},也可以是{+, -, -, -, +, -, +, +}。这两种情况都具有此问题中定义的“最小双调性”。
  • @CodeHunter 哦,我明白了。所以整个数组并不明显。那么,在交换导致相邻元素相同的情况下,如何计算结果数组的双调性?你对a[i] == a[i - 1]时会发生什么没有条件。
  • 交换之后。例如a={1, 3, 4, 1}。根据您的规则,这是有效的。我们将 3 与最后的 1 交换。然后我们需要计算双调性,但这不再可能。
  • 好的。请注意,使用此规则,您不再需要保证初始数组中的相邻元素是不同的。现在它们可以相同了,这彻底改变了问题。

标签: arrays algorithm


【解决方案1】:

紧急更新:T3 不成立!

考虑 α = [0, 7, 8, 3, 4, 10, 1, 6, 9, 2, 5]。没有 Sij(α) 可以将 |B(α)| 降低 2 以上。

正在考虑修改方法……

警告

此解决方案仅在没有相等的数组元素时才有效。

通过编辑答案随意提出概括。

如果您想跳过无聊的部分,请直接进入结论

简介

让我们在数组 a 上定义交换运算符 Sij

Sij(a) : [… ai, … aj, …] → [… aj, … ai, …] ∀i, j ∈ [0; |a|) ∩ ℤ : i ≠ j

我们也将双调性称为B(a),并更正式地定义它:

显而易见的事实:

  1. 交换是对称的:

    Sij(a) = Sji(a)

  2. 如果它们的目标位置不相交,则两个交换是独立的:

    Sij(Skl(a)) = Skl(Sij( a)) ∀i, j, k, l : {i, j} ∩ {k, l} = ∅

  3. 两个依赖 2 的交换相互撤消:

    Sij(Sij(a)) = a

  4. 两个依赖于 1 的掉期遵守以下规定:

    Sjk(Sij(a)) = Sij(Sik( a)) = Sik(Sjk(a))

  5. 对于同样大小的数组,双调性差异始终是均匀的:

    (B(a) – B(a')) mod 2 = 0 ∀a, a' : |a| = |a'|

    当然,∀i : 0 ,

    B([ai–1, ai]) – B([a'i–1, a 'i]) = sgn(ai – ai–1) – sgn(a'i – a'i–1),

    可以是 1 – 1 = 0,或 1 – –1 = 2,或 –1 – 1 = –2,或 –1 – –1 = 0,以及任意数量的 ±2`s 和 0` s 相加得出一个偶数的结果。

    注意:只有当 a 中的所有元素彼此不同时才成立,a' 也是如此!

定理

[T1] |B(Sij(a)) – B(a)| ≤ 4 ∀a, Sij(a)

不失一般性,我们假设:

  • 0
  • j – i ≥ 2
  • ai–1i+1
  • aj–1j+1

根据 ai,可能有 3 种情况:

  1. ai–1i i+1: sgn(ai – ai–1) + sgn(ai+1 – ai) = 1 + 1 = 2
  2. aii–1 i+1: sgn(ai – ai–1) + sgn(ai+1 – ai) = –1 + 1 = 0
  3. ai–1i+1 i: sgn(ai – ai–1) + sgn(ai+1 – ai) = 1 + –1 = 0

当改变 ai 并保持 a 的所有其他元素不变时,|B(a') – B(a )| ≤ 2(其中 a' 是结果数组,上述 3 种情况也适用),因为 B(a) 的其他项没有改变它们值,除了来自 ai 的 1 邻域的那两个。

Sij(a) 表示上述情况发生两次,一次为 ai aj 一次。

因此,|B(Sij(a)) – B(a)| ≤ 2 + 2 = 4.

类似地,对于每个角,j – i = 1 的最大值。可能的 delta 为 2,即 ≤ 4。

最后,这直接推断为 ai-1 > ai+1aj-1 > aj+1.

QED

[T2]   ∀a : |B(a)| ≥ 2 ∃Sij(a) : |B(Sij(a))| = |B(a)| – 2

{证明进行中,需要睡觉}

[T3]   ∀a : |B(a)| ≥ 4 ∃Sij(a) : |B(Sij(a))| = |B(a)| – 4

{证明进行中,需要睡觉}

结论

T1T2T3,最小化所需的交换次数 |B(a)|强>等于:

⌊|B(a)| / 4⌋ + ß,

其中 ß 等于 1 如果 |B(a)| mod 4 ≥ 2,否则为 0。

【讨论】:

  • 真的很感谢你的努力! +1。目前,我找不到任何反例,但我鼓励与此问题相关的人请验证这一点。另外,您能否解释一下 T1 的假设,尤其是最后 2 个?可能存在a[i–1] &gt; a[i+1]a[j–1] &lt; a[j+1] 的情况,反之亦然。我的结论是,在这种情况下,B(a) 最终会取消,而 T1 仍将保持不变。你能确定我对此的结论吗?
  • @CodeHunter 完全正确。可能会出现一种情况,首先是 +2,其次是 –2(反之亦然),因此它们不会在最终总和中添加任何内容。 [UPD:] 添加证明……
  • @CodeHunter 但我认为如果它用于工业实践,你必须知道确切的交换。正如您提到的“交易数据分析模式”,您不想要一种可以告诉您确切掉期的机制吗?
  • @CodeHunter 很抱歉违反了我今天证明这一点的承诺。正在努力。 T2 的主要思想是:要达到至少 B(a) = ±2a 必须有至少 3 个连续的链增量或decr。值(双调链±→±)。处理 4 链 (± → ± → ±) 或更多很简单,因为我们可以取任意 2 个非边缘值并将它们交换 (± → ∓ → ± ),从而破坏了链条。所以,在 T2 中剩下要证明的是 ∓ → ± → ± → ∓ 双调链(我们称它们为 N 链,因为如果绘制它们类似于 Ns在斜线中:/\\/) 也能够被适当地中断。
  • @hidefromkgb:酷。我实际上已经测试了您在大多数测试用例中给出的上述逻辑,但没有失败。我认为这个想法是正确的!
猜你喜欢
  • 1970-01-01
  • 2018-07-08
  • 2019-11-14
  • 2019-08-08
  • 2014-10-13
  • 1970-01-01
  • 2013-04-08
  • 1970-01-01
相关资源
最近更新 更多