候选人在数组中找到多数元素

时间:2013-04-18 15:49:47

标签: arrays algorithm

我不是问如何在数组中找到多数元素,这已在此处详细讨论Find majority element in array

我的问题如下:

有一个数组arr[1...2n],此数组的多数元素为maj,现在我将使用以下规则删除arr中的元素,

如果arr[i] == arr[i + 1],请删除arr[i],i = 1,3,5,...,2n - 1; 否则,如果arr[i] != arr[i + 1],请删除arr[i]arr[i + 1],i = 1,3,5,...,2n - 1.

然后我们可以获得一个新数组new_arrnew_arr的多数元素的候选者是new_maj, 是否有证据证明new_maj == maj

3 个答案:

答案 0 :(得分:1)

是的,有证据。

我们只对元素对a[i],a[i+1]i奇数感兴趣。如果a[i]=a[i+1],我们称这样一对为“好”。其他对是“坏”。与多数候选人相等的元素是“常规”。一对好的groovy元素是一对groovy对。

关于良好配对的简单事实是至少有一半的好配对是常规的。假设不是这样;然后在良好的配对中,严格不到一半的元素是常规的,在坏配对中,不超过一半的元素是常规的。总的来说,严格来说,不到一半的元素是常规的。这是一个矛盾。

所以我们已经确定至少有一半的好对子是常规的。

现在消除所有坏对。仍然至少有一半的元素是常规的(因为只剩下好的对,其中至少有一半是常规的)。

现在从好的对中消除所有其他元素。仍然至少有一半的元素是常规的(因为每个元素的数量只减半)。

结论证明。

答案 1 :(得分:0)

定义N = 2 n。该数组包含N个元素。

M定义为maj在数组中出现的次数。 “多数元素”的定义是M > N/2

现在将数组分成对p[1] ... p[n]。将q0定义为包含maj的零实例的对数。将q1定义为仅包含一个maj实例的对数。将q2定义为恰好包含两个maj实例的对数。

然后N = 2 q0 + 2 q1 + 2 q2M = q1 + 2 q2

代入定义多数元素的不等式,并简化:

        M > N / 2
q1 + 2 q2 > (2 q0 + 2 q1 + 2 q2) / 2
q1 + 2 q2 > q0 + q1 + q2
     2 q2 > q0 + q2
       q2 > q0

因此,包含两个maj实例的对数超过了包含maj的零实例的对数。

现在,在运行算法后,将M'定义为新数组中maj出现的次数。该算法为每个maj对删除一个q1,为每个maj对删除一个q2。所以M' = M - q1 - q2

N'定义为算法生成的新数组的大小。该算法为每个q1对删除两个元素,为每个q2对删除一个元素。

但我们不知道算法删除了每个q0对的元素数量。一些q0对包含两个不同的元素,算法删除两者。但其他q0对包含相同的(非maj)元素,算法只删除一个。

一个极端是所有q0对都被完全删除。在这种情况下,算法会删除2 q0个元素,所以

N - 2 q1 - q2 - 2 q0 ≤ N'

另一个极端是每个q0对中只删除一个元素。在这种情况下,算法会删除q0个元素,所以

N - 2 q1 - q2 - q0 ≥ N'

让我们回到“多数元素”的定义并做一些代数:

          M > N / 2
M - q1 - q2 > N / 2 - q1 - q2
M - q1 - q2 > (N - 2 q1 - 2 q2) / 2
M - q1 - q2 > (N - 2 q1 - q2 - q2) / 2

左侧是M'

M' > (N - 2 q1 - q2 - q2) / 2

我们可以将右侧变为N' / 2吗?首先,将两边乘以2:

2 M' > N - 2 q1 - q2 - q2

回想一下,我们证明了q2 > q0。因此

2 M' > N - 2 q1 - q2 - q2 > N - 2 q1 - q2 - q0

并且,因为我们推断了N - 2 q1 - q2 - q0 ≥ N'

2 M' > N - 2 q1 - q2 - q0 ≥ N'

所以

2 M' > N'
  M' > N' / 2

因此maj在新数组中出现足够的次数成为新数组的主要元素。 QED。

答案 2 :(得分:0)

这是我的证明变体:

考虑对arr [i]和arr [i + 1]的4种情况(反之亦然,对的顺序并不重要),我很奇怪。让 maj 成为主要元素, min 是任何次要元素:

  1. maj maj - 让这些对的数量为 a
  2. maj min - 让这些对的数量为 b
  3. min1 min2 - 让这些对的数量为 c ,min1!= min2
  4. min1 min1 - 让这些对的数量 d
  5. a,b,c,d都是> = 0。

    案例1对主要元素的原始总和贡献2 | maj |并减少主要元素的最终总和| maj |' (执行算法后)1

    案例2对| maj |贡献1和1到| min |,所有次要元素的原始总和,并减少| maj |'由1和| min |'由1

    案例3贡献2到| min |并减少| min |'由2

    案例4贡献2到| min |并减少| min |'由1

    因此,原始数组arr []中的主要元素总数为:

    |maj| = 2a + b
    

    所有次要元素的数量为:

    |min| = b + 2c + 2d
    

    从| maj | > |分| ,

    2a + b > b + 2c + 2d
        2a > 2c + 2d
         a > c + d
    

    运行算法后,新的主要元素数由下式给出:

    |maj|' = |maj| - a - b
    

    以及新的次要元素数量为:

    |min|' = |min| - b - 2c - d
    

    代替我们:

    |maj|' = 2a + b - a - b           = a
    |min|' = b + 2c + 2d - b - 2c - d = d
    

    因为我们从上面知道c + d< a,和a,c,d都是> = 0,我们有

    a > c + d =>
    a > d =>
    |maj|' > |min|'
    

    因此 maj 仍然是新数组中的主要元素。