问题描述:

Design an algorithm that, given a list of n elements in an array, finds all the elements that appear more than n/3 times in the list. The algorithm should run in linear time ( n >=0 )
You are expected to use comparisons and achieve linear time. No hashing/excessive space/ and don't use standard linear time deterministic selection algo

解答:

借鉴俄罗斯方块的玩法,先给个直观的例子。对于数组 4 3 3 2 1 2 3 4 4 7,按照类俄罗斯方块的玩法,当7要往下落的时候,屏幕上会呈现这个场景

4
4 3 2
4 3 2 1 _

当7落下时,获得了

4
4 3 2
4 3 2 1 7

此时最后一行元素数目满了(最后一行的大小为5),将其删除,继续落数字。直到所有数字都落下来了。此时数目超过n/5的元素一定在最后一行(因为假设数字a的个数超过n/5,删除操作最多执行了n/5次,所以最后必然a还在最后一行中)。但是,最后一行中的元素也有可能不是我们要的。此时需要扫描一下来确定。

同样的算法对于任意的m(m为正整数)均适用。

给出代码:

   1:  #include <iostream>
   2:  #include <map>
   3:  #include <algorithm>
   4:  typedef std::map<int, int> Map;
   5:   Map findOverNth(int arr[], int size, int n)
   6:  {
   7:      Map ret_map; 
   8:      typedef Map::value_type Elem; //pair<CONST int, int>
   9:      int total = 0;
  10:      std::for_each(arr, arr + size, [&, n](int val) 
  11:      {
  12:          auto ret_pair = ret_map.insert(Elem(val, 0));
  13:          ++(*ret_pair.first).second; ++ total;
  14:          if (ret_map.size() == n)
  15:              for (auto iter = ret_map.begin(); iter != ret_map.end(); )
  16:              {
  17:                  --(*iter).second; -- total;
  18:                  if ((*iter).second == 0)
  19:                      ret_map.erase(iter++);
  20:                  else
  21:                      iter++;
  22:              }
  23:      });
  24:      std::for_each(ret_map.begin(), ret_map.end(), [](Elem &elem) {elem.second = 0;});
  25:      std::for_each(arr, arr + size, [&ret_map](int val) {if (ret_map.find(val) != ret_map.end()) ret_map[val] ++;});
  26:      for (auto iter = ret_map.begin(); iter != ret_map.end(); )
  27:      {
  28:          if ((*iter).second <= size / n)
  29:              ret_map.erase(iter++);
  30:          else 
  31:              iter++;
  32:      }
  33:      return ret_map;
  34:  }
  35:  using namespace std;
  36:  int main()
  37:  {
  38:      //int arr[] = {5,6,7,8, 10, 4,4, 4, 4,1, 1,1};
  39:      int arr[] = {5,6,7,8, 10, 10, 10,10,10,10, 4,4, 4, 4,4,1, 1,1,1};
  40:      auto a_map = findOverNth(arr, sizeof(arr)/sizeof(int), 4);
  41:      cout<<sizeof(arr)/sizeof(int)<<endl;
  42:      //cout<<a_map.size()<<endl;
  43:      for each(auto elem in a_map)
  44:      {
  45:          cout<<elem.first<<" "<<elem.second<<endl;
  46:      }
  47:  }

线性时间常数空间找到数组中数目超过n/5的所有元素的更多相关文章

  1. 【ShareCode】不错的技术文章 -- 如何使用异或(XOR)运算找到数组中缺失的数?

    如何使用异或(XOR)运算找到数组中缺失的数? 今天给大家分享一篇关于使用XOR(异或)运算找到数组中缺失的数的问题. 在一次Javascript面试中,有这么一个问题: 假设有一个由0到99(包含9 ...

  2. php array_rand()函数从数组中随机选择一个或多个元素

    php使用array_rand()函数从数组中随机选择一个或多个元素的方法. 使用array_rand() 函数从数组中随机选出一个或多个元素,并返回.  array_rand(array,numbe ...

  3. Java 找到数组中两个元素相加等于指定数的所有组合

    思路1:可以用hash表来存储数组中的元素,这样我们取得一个数后,去判断sum - val 在不在数组中,如果在数组中,则找到了一对二元组,它们的和为sum,该算法的缺点就是需要用到一个hash表,增 ...

  4. leetcode-1 Two Sum 找到数组中两数字和为指定和

     问题描写叙述:在一个数组(无序)中高速找出两个数字,使得两个数字之和等于一个给定的值.如果数组中肯定存在至少一组满足要求. <剑指Offer>P214(有序数组) <编程之美& ...

  5. [LeetCode] 448. Find All Numbers Disappeared in an Array 找到数组中消失的数字

    题目描述 给定n个数字的数组,里面的值都是1-n,但是有的出现了两遍,因此有的没有出现,求没有出现值这个数组中的值有哪些. 要求不能用额外的空间(除了返回列表之外),时间复杂度n 思路 因为不能用额外 ...

  6. 《剑指offer》-找到数组中重复的数字

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

  7. majority element(数组中找出出现次数最多的元素)

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  8. 每日一道 LeetCode (8):删除排序数组中的重复项和移除元素

    每天 3 分钟,走上算法的逆袭之路. 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee ...

  9. 【原创】leetCodeOj --- Majority Element 解题报告(脍炙人口的找n个元素数组中最少重复n/2次的元素)

    题目地址: https://oj.leetcode.com/problems/majority-element/ 题目内容: Given an array of size n, find the ma ...

随机推荐

  1. App.config的学习笔记

    昨天基本弄清config的使用之后,再看WP的API,晕了.结果WP不支持system.configuration命名空间,这意味着想在WP上用App.config不大可能了. WP具体支持API请查 ...

  2. VIM编辑器常用功能整理笔记

    vim编辑器 vi : visual Inertface 可视化接口 vim : vi improved 扩展版 语法着色 模式化编辑器: 编辑模式(命令模式): 默认模式 输入模式: 末行模式: 等 ...

  3. jquery绑定事件失效的情况(转)

    原文地址:http://www.thinksaas.cn/group/topic/348453/ jQuery中文api地址:http://www.jquery123.com/api/ jQuery官 ...

  4. 2.Knockout.Js(监控属性Observables)

    前言 1.创建一个ViewModel <script type="text/javascript"> //1.创建一个ViewModel var myViewModel ...

  5. iOS学习之Object-C语言继承和初始化方法

    一.继承 1.面向对象的三大特性:封装,继承,多态.      面向对象提供了继承特性.把公共的方法和实例变量写在父类里,子类只需要写自己独有的实例变量和方法即可.继承既能保证类的完整,又能简化代码. ...

  6. verilog运算符及表达式

    1.运输符 算术运算符(+,-,X,/,%) 赋值运算符(=,<=) 关系运算符(>,<,>=,<=) 逻辑运算符(&&,||,!)//与或非 条件运算符 ...

  7. verilog实现16位五级流水线的CPU带Hazard冲突处理

    verilog实现16位五级流水线的CPU带Hazard冲突处理 该文是基于博主之前一篇博客http://www.cnblogs.com/wsine/p/4292869.html所增加的Hazard处 ...

  8. algorithm之改变序列算法--待解决

    简述:改变序列算法,参见http://www.cplusplus.com/reference/algorithm/?kw=algorithm 待解决问题:iterator_traits.std::mo ...

  9. 随堂作业——到底有几个“1”(C++)

    一.设计思路 在课堂上讨论的时候,老师提出的思路是利用之前的结果计算出比它更大的数字的“1”.但是我不是这么想的,我是把输入的正整数每位上的数都分解出来计算.如abc,就先算c,再加上b,最后再加上a ...

  10. xml基础学习笔记01

    注意:刚刚看了网上对于XML中的标签,节点和元素?到底应该怎么表述?起初我也有这个疑惑,现在我的想法是:下面出现node的应称作节点,节点对象.element应称作元素,毕竟这更符合英文的本意.至于标 ...