LeetCode | 229. Majority Element II 限制时间空间数学原理题解析与证明

Given an integer array of size n, find all elements thatappear more than  n/3  times. The algorithm should run in linear timeand in O(1) space.

这题是真的难证明

这里给你一个数组,要你求出所有出现数量多于  n/3 的数字,这题方法简单,但是原理非常复杂,看懂答案只用了5分钟,弄懂原理用了整个上午和下午,首先用两个数a,b,n1,n2来分别记录峰1,峰2,峰1的数量,峰2的数量,可以证明,当求 所有多于⌊ n/m ⌋的数的时候,只要定义(m-1)个不同的数字,以及(m-1)个不同的计数,将所有计数初始化为0,所有数字初始化为不同值,记住,一定要是不同值,但是可以是任何值,要不然不能保证计算过程中所有数字的不同,最后可能导致result里面添加多个相同的数字

证明方法是,当发现num[i]和a1,a2,…am-1里面一个数字相同的时候,假设是ak,将nk加一,当发现num[i]和任何一个数字都不同的时候,替换掉任何一个nk==0的数字,也就是ak=num[i],nk++,就这样一直计算下去,可以证明,当计算完成的时候,a1,a2…am-1里面一定存在所有出现次数多于⌊ n/m ⌋的数,这时只要重新检查a1,a2…am-1看那个出现的次数多于⌊ n/m ⌋就行了

这里简单的证明一下,假设有m个区间,每个区间有t个数,那么n可表示成n=m*t+z,这里z=0~m-1,这里假设有一组多于⌊ n/m ⌋,设这组为A,那么他的数量num(A)>=t+1,<=n,可以证明,每一个A里面的数可以和m-1个其他数消除,每m-1个其他数可以消除一个A,我们现在来证明当算法进行到最后A一定消除不完。

我们使A的数量最少,为t+1,非A的数尽可能的多,为(m-1)*t+m-1-1=n-t-1,非A的数能消耗A的数最多为⌊ (m-1)*t+m-1-1 ⌋=⌊ t-1/(m-1) ⌋<t+1,因此A的数最后一定有剩,A的数有剩则其一定存在于a1,a2…am-1里面,否则其一定被消耗完了,这和假设不符,其他各个多于⌊ n/m ⌋的数也可以同样证明,

class Solution {

public:

   vector<int> majorityElement(vector<int>& nums) {

      inta, n1, b, n2, num; vector<int> result;

      num= nums.size() / 3;

      n1= n2 = 0; a = 0; b = 1;

      for(int u : nums)

      {

            if(u == a)

            {

                  n1++;

            }

            else

                  if(u == b)

                       n2++;

                  else

                  if(n1==0)

                  {

                       a= u; n1++;

                  }

                  else

                  if(n2==0)

                  {

                       b= u; n2++;

                  }

                  else

                  {

                       n1--;n2--;

                  }

      }

      n1= 0; n2 = 0;

      for(int u : nums)

      {

            if(u == a) n1++;

            if(u == b) n2++;

      }

      if(n1 > num) result.push_back(a);

      if(n2 > num) result.push_back(b);

      returnresult;

}

};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值