您的位置:首页 > 编程语言

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, 所以请大家指出!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编程之美