问题描述:

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. Redhat 6环境下安装Oracle 12c的方法

    Step 1: 要在Linux上安装Oracle,需要在安装Oracle之前安装好相应的软件包,在不同操作系统环境下,对软件包的要求各不相同.具体对应的软件包,见官网文档:https://docs.o ...

  2. ASP.NET基础笔记

    MSDN:                                                                                                ...

  3. Android中BaseAdapter的基本用法和加载自定义布局!

    public class MainActivity extends Activity { ListView listView = null; @Override protected void onCr ...

  4. swift 命令行工具初探

    亲爱的同学们好,今天我们要介绍这么一个东西.相信有过解释型语言(PHP,Ruby,等)使用经验的同学会更加熟悉,就是 Swift 也为我们提供了命令行运行工具,俗称 REPL.好了,我们进入正题,在安 ...

  5. 什么是锚点(AnchorPoint)

    1.锚点通常是图形的几何中心, AnchorPoint(x,y)的两个参量x和y的取值通常都是0到1之间的实数,表示锚点相对于节点长宽的位置. 例如,把节点左下角作为锚点,值为(0,0): 把节点的中 ...

  6. JPA学习---第十一节:JPA中的多对多双向关联实体定义与注解设置及操作

    1.定义实体类,代码如下: (1).学生实体类: package learn.jpa.entity; import java.util.HashSet; import java.util.Set; i ...

  7. 玩耍Hibernate系列(一)--基础知识

    Hibernate框架介绍: Hibernate  ORM  主要用于持久化对象(最常用的框架) Hibernate  Search 用于对对象进行搜索,底层基于Apache Lucene做的 Hib ...

  8. Careercup - Microsoft面试题 - 6282862240202752

    2014-05-11 03:56 题目链接 原题: Given an integer array. Perform circular right shift by n. Give the best s ...

  9. 在一台电脑访问另一台电脑的mysql数据库,并增加和剥夺权限

    1.    假设MySQL服务器安装在ip地址为192.168.105.3的主机上面 2.    再假设客户端安装在ip为192.168.105.100的机子上 3. 首先在ip为192.168.10 ...

  10. 浏览器不支持HTML5

    有些浏览器并不支持HTML5中的新增元素,如IE8或更早版本.想要应用样式,可以头部标记<head>中加入下面JavaScript代码 <html> <head> ...