给定一个长度为N的数组,找出出现次数大于n/2,n/3的数,要求时间复杂度O(n),空间复杂度O

Posted 不搞事情和咸鱼有什么区别

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了给定一个长度为N的数组,找出出现次数大于n/2,n/3的数,要求时间复杂度O(n),空间复杂度O相关的知识,希望对你有一定的参考价值。

  先讨论出现次数大于n/2的数字,如果这样的数字存在,那么这个数出现的次数大于其他数出现的次数的总和。

在数组A中,我们定义两个数据集合a1,a2。a1为出现次数大于n/2的数的集合,a2为其余数组成的集合。对于数组

A中元素a、b,假设a不等于b,那么有两种情况,分别为:a属于a1,b属于a2;a属于a2,b属于a2。对于这两种情况,如

果把a、b从数组A中去掉,集合a1的size依旧是大于a2的。按照这个思路,我们有如下代码:

   int m;
    int count = 0;
    for (auto num : nums) 
   {
     // 初始的时候为1
if (0 == count) { m = num; ++count; } else {
       // 相等的话我们加一 不相等就同时去掉
if (m == num) ++count; else --count; }
  }

 

那么对于找出次数大于1/3的情况,我们最多存在两个这样的数字n,m。也就是说任一的n或者m与剩下的部分的比例为1:1,这就转化为求次数大于1/2的情况了。代码如下:

int m, n; //最多存在2个出现次数超过 1/3 的元素
    int cm, cn; //对应 m 和 n 的统计
    for (auto num : nums) {
        if (cm == 0 || num == m) {
            m = num;
            ++cm;
        }
        else if (cn == 0 || num == n) {
            n = num;
            ++cn;
        }
        else {
            --cm;
            --cn;
        }
    }

可以简单的理解为,如果从不超过1/3的那部分数据中去掉一个数字,那么n,m对应的数据集合分别要去掉一个数字,n,m对应的数据集size大于1/3的条件才不会变。

 

以上是关于给定一个长度为N的数组,找出出现次数大于n/2,n/3的数,要求时间复杂度O(n),空间复杂度O的主要内容,如果未能解决你的问题,请参考以下文章

牛客网在线编程:n个数中出现次数大于等于n/2的数

剑指 Offer 39. 数组中出现次数超过一半的数字

寻找众数

169. 求众数

给你一个长度为 n 的数组,其中只有一个数字出现了大于等于 n/2 次,问如何使用优秀的 时空复杂度快速找到这个数字。

LeetCode169 多数元素