2.3 寻找"水贴王"
2015-08-11 20:38
232 查看
1. 前言
本文的一些图片, 资料 截取自编程之美2. 问题描述
3. 问题分析
对于这个题目, 书上给出了三种思路第一种 : 先遍历一次所有的帖子, 统计出 <发帖人, 发帖次数>, 然后在遍历一次映射, 找出发帖次数超过一半的发帖人 即为所求
第二种 : 将所有的id[包括重复]进行排序, 然后最中间的id即为所求
第三种 : 逐渐减小问题的规模的算法, 每一次删除两个不同的id, 那么剩下的id列表中, 水贴王的出现次数必然也满足超过一半[因为, 如果删除的两个id中没有水贴王id, 水贴王id出现的次数必然超过一半 [x/ sum => x/ sum-2], 如果删除的两个id中有一个为水贴王id, 则水贴王id出现的次数仍然会超过一半[x/ sum => x - 1/ sum - 2] ]
当然上面的思路还有一个条件就是 : 2 * x > sum [这个这个对于, 删除两个id中水贴王id出现一次可是必杀技, 证明不等式是靠他的]
4. 代码
/** * file name : Test10FindWaterPasteKing.java * created at : 8:46:19 AM May 20, 2015 * created by 970655147 */ package com.hx.test03; public class Test10FindWaterPasteKing { // 找出水贴之王 其id出现超过一半 public static void main(String []args) { // int[] allIds = Tools.generateWaterPasteIds(100, 30); int[] allIds = {65, 96, 65, 54, 65, 79, 65, 8, 65, 5, 65, 21, 65, 43, 65, 90, 65, 83, 65, 39, 65, 48, 65, 76, 65, 79, 65, 57, 65, 65 }; findWaterPasteKing01(allIds); findWaterPasteKing02(allIds); findWaterPasteKing03(allIds); } // 先将所有的id进行统计出现的次数 在找出超过一半的id public static void findWaterPasteKing01(int[] allIds) { Arrays.sort(allIds); Map<Integer, Integer> hm = new HashMap<Integer, Integer>(); for(int i=0; i<allIds.length; i++) { if(hm.containsKey(allIds[i]) ) { hm.put(allIds[i], (hm.get(allIds[i]) + 1) ); } else { hm.put(allIds[i], 1); } } int half = allIds.length / 2; for(Entry<Integer, Integer> entry : hm.entrySet()) { if(entry.getValue() > half) { Log.log(entry.getKey()); break; } } } // 先将所有的id进行排序 直接取1/2 长度出的id public static void findWaterPasteKing02(int[] allIds) { Arrays.sort(allIds); Log.log(allIds[allIds.length / 2]); } // 思路 : 每次去掉两个不同的id cnt表示还需要删除的与candidate不同的数据的个数 // 将问题的规模 逐渐缩小 public static void findWaterPasteKing03(int[] allIds) { int candidate = -1, cnt = 0; for(int i=0; i<allIds.length; i++) { if(cnt == 0) { candidate = allIds[i]; cnt ++; } else { if(allIds[i] == candidate) { cnt ++; } else { cnt --; } } } Log.log(candidate); } }
5. 运行结果
6. 总结
前两种思路 想到是不难的, 但是第三种思路, 却是非常巧妙的当水贴王id 小于 (id总数/ 2), 的时候, 删除的两个id中存在一个水贴王id, 会导致水贴王id所占的比率下降
当水贴王id 等于 (id总数/ 2),的时候, 删除的两个id中存在一个水贴王id, 会导致水贴王id所占的比率不变
当水贴王id 大于 (id总数/ 2),的时候, 删除的两个id中存在一个水贴王id, 会导致水贴王id所占的比率增大
注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!
相关文章推荐
- 《编程之美》
- 2012年终碎语,编程之美
- 失业在家的学习笔记-第二天
- 编程之美2015初赛A
- 编程之美初赛B
- 程序员编程艺术3:寻找最小的k个数
- 编程之美2013全国挑战赛资格赛第1题
- 编程之美2013全国挑战赛资格赛第3题
- 编程之美3.8:求二叉树节点的最大距离
- 瓷砖覆盖地板问题
- Best Time to Buy and Sell Stock
- 编程之美2014格格取数
- 编程之美——象棋将帅问题
- 编程之美——烙饼排序问题
- 连连看游戏判断两个块是否可以消去,并计算最小转弯数
- 《编程之美》——中国象棋将帅问题
- 《编程之美》——求二叉树中节点的最大距离(非递归)
- 《编程之美》——求二叉树中节点的最大距离(非递归)
- 《编程之美》——中国象棋将帅问题
- 连连看游戏判断两个块是否可以消去,并计算最小转弯数