题目

我们有一个ID列表,其中存着某论坛所有帖子的作者ID。
另外,我们已经得到准确情报,在这个长长的列表中,有3个ID,每个出现次数都超过了总数的1/4。这毫无疑问是职业水军干的。
你的任务是快速地找到这3个ID。
可以先考虑列表较短的时候,比如:
1,4,1,1,2,3,3,2,2,3
则所求ID为:1,2,3

分析

最容易想到的方案是:弄一个Map,记录每一个ID的出现次数。
最后再扫描一次,把次数大于总数的1/4的 ID 输出出来。
这个方案的问题在于:当列表较大,并且ID分布比较散的时候,我们这个Map可能很大,甚至是内存装不下。
有没有更节省的方案呢?

如果从实用性的角度讲,我们可以随机抽取若干个位置的ID,比如抽取10000个,从统计学理论(或直觉)可知,这个采样,应该保留了原列表的特征。所以对这个采样进行扫描处理就可以了。
但是不管怎么说,总有人说这个方法不严谨,并且有偷机取巧的意思。。。。

好吧,看看另一个思路。
我们注意到,3个ID发帖总数超过了3/4,也就是说,其他人发的帖子加起来也没有水军中一个人发的多!
于是乎,有人设计一个擂台赛:
擂台上可以同时容纳 3 个人,且开始是空的。
现在,队列中每个选手依次出场。
如果台上有自已人, 就把那个人的生命值加 1
如果台上有空位子,就站上台,且开始的生命数是 1
否则,就把台上 3 个人的生命值都减 1
生命值减到 0 的人死亡,把台上的位置空出来。

到最后,剩在台上的 ID,就是所求的 ID

代码

先来个笨办法的。
这在绝大多数场合是足够用的。

//problem003
import java.util.*;
public class A
{static List<Integer> f(int[] data){Map<Integer,Integer> map = new HashMap<Integer, Integer>();for(int x: data){Integer num = map.get(x);if(num==null) map.put(x,1);elsemap.put(x, num+1);}List<Integer> res = new ArrayList<Integer>();for(int x: map.keySet()){if(map.get(x) > data.length / 4.0) res.add(x);}return res;}public static void main(String[] args){int[] data = {2,3,7,3,2,1,1,2,2,4,3,1,3,2,3,6,1,1,1,3,8,3,1,9,2,1,2,5,3,2,       };System.out.println(f(data));}
}

下面是高效的算法。

//problem003
import java.util.*;
public class B
{static Set<Integer> f(int[] data){Map<Integer, Integer> map = new HashMap<Integer, Integer>();for(int x: data){if(map.get(x) != null){map.put(x, map.get(x)+1);continue;}if(map.size()<3){map.put(x, 1);continue;}for(Iterator<Integer> it=map.keySet().iterator(); it.hasNext();){int key = it.next();map.put(key, map.get(key)-1);if(map.get(key)==0) it.remove();             }   }return map.keySet();}public static void main(String[] args){int[] data = {2,3,7,3,2,1,1,2,2,4,3,1,3,2,3,6,1,1,1,3,8,3,1,9,2,1,2,5,3,2,        };System.out.println(f(data));}
}

这里需要初学java童鞋注意的是:
不能直接在Map的迭代中进行删除键的动作。
必须使用 Iterator,并且只对当前 Iterator 才能remove

详解

如果对为什么这样设计可行还是心里没底,可以在“千聊”上搜这个标题。
或者,手机扫下图,添加关注。
(最好是自已先仔细想想,挺有趣的)

发现水贴(算法入门题目003)相关推荐

  1. 猴子搬香蕉(算法入门题目005)

    题目 A 地有一堆香蕉,共 w 只. 一只猴子要把香蕉从 A 地运输到 B 地. 两地相距 s 里. 猴子每次最多只能背 c 只香蕉. 无论背多少香蕉(甚至不背),猴子每走 1 里路,会吃掉 1 只香 ...

  2. LeetCode算法入门- Multiply Strings -day18

    LeetCode算法入门- Multiply Strings -day18 题目介绍 Given two non-negative integers num1 and num2 represented ...

  3. 算法入门刷题笔记 Day10 - A - 拓扑排序·一 -- D - K-th Path

    写在前面 好久没更新公众号和博客了,因为最近在研究新的方向,所以很少发文. 笔者接触编程只有一年,这一年间主要研究启发式算法在运筹学中的应用.但是由于编程基础薄弱,在进一步研究复杂运筹学问题时发现基础 ...

  4. 算法入门刷题笔记 Day2 K - Coat of Anticubism L - Five-In-a-Row M - Island Puzzl......

    写在前面 好久没更新公众号和博客了,因为最近在研究新的方向,所以很少发文. 笔者接触编程只有一年,这一年间主要研究启发式算法在运筹学中的应用.但是由于编程基础薄弱,在进一步研究复杂运筹学问题时发现基础 ...

  5. poj题目详细分类及算法推荐题目

    DP:  1011   NTA                 简单题  1013   Great Equipment     简单题  1024   Calendar Game       简单题  ...

  6. 模式识别之Earley算法入门详讲

    引言:刚学习模式识别时,读Earley算法有些晦涩,可能是自己太笨.看了网上各种资料,还是似懂非懂,后来明白了,是网上的前辈们境界太高,写的最基本的东西还是非常抽象,我都领悟不了,所以决定写个白痴版的 ...

  7. 【算法入门】深度优先搜索(DFS)

    深度优先搜索(DFS) [算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍 ...

  8. 贝叶斯公式由浅入深大讲解—AI基础算法入门

    1 贝叶斯方法 长久以来,人们对一件事情发生或不发生的概率,只有固定的0和1,即要么发生,要么不发生,从来不会去考虑某件事情发生的概率有多大,不发生的概率又是多大.而且概率虽然未知,但最起码是一个确定 ...

  9. 贝叶斯公式由浅入深大讲解—AI基础算法入门【转】

    本文转载自:https://www.cnblogs.com/zhoulujun/p/8893393.html 1 贝叶斯方法 长久以来,人们对一件事情发生或不发生的概率,只有固定的0和1,即要么发生, ...

最新文章

  1. 特斯拉撞了警车:辅助系统Autopilot全程开启,连撞两车还没自动停下
  2. nodejs redis 发布订阅_太赞了:Spring boot+redis实现消息发布与订阅
  3. spark java 计数_spark程序——统计包含字符a或者b的行数
  4. pause pod 什么是pod_Kubernetes 自主式Pod清单 干货太多先马住慢慢看
  5. ASP.NET设置发帖时间间隔不超过30秒
  6. jquery读写cookie
  7. Silverlight 5 RC新特性探索系列:15.Silverlight 5 RC 对OpenType字体属性的支持
  8. 数据管理系统 php,dms: 数据管理系统;采用mvc模型,存php原生操作无模板引擎;响应式前端框架huiadmin套用,扁平化风格,兼容移动端;...
  9. 风控模型——评分卡模型
  10. python format 用法详解
  11. 杀毒软件巨头荣光不复 瑞星信息去年亏损7300万元
  12. 在JavaScript中改变鼠标指针样式的方法
  13. linux客户端连接iscsi,配置ISCSI客户端(LINUX)redhat5-iSCSI-INITIATOR
  14. 牛顿迭代法 matlab程序
  15. easyUI tree 自定义图标
  16. win10安装keras theano
  17. 观点 | 未来的货币,是可编程的电子货币
  18. python 高阶函数作业(3.16)
  19. 生活网官司难断爱帮网大众点评均称胜诉
  20. 不同格式图片相互转换的开源库分享

热门文章

  1. 峰任:企业开展网络营销的关键是自身
  2. i5 10400f和i7 7700哪个性价比高
  3. 云计算及其虚拟化技术
  4. div中内容水平垂直居中
  5. rufus 一款好用的linux u盘,光盘刻录工具
  6. ps2021神经网络滤镜不能用,ps2021神经滤镜不能下载
  7. Spacebuilder可以做什么?
  8. 关于c++的批量注释快捷键使用及调整
  9. 表单数据序列化之serialize()、serializeArray()方法的使用
  10. 【特征提取】基于matlab共振峰估计【含Matlab源码 550期】