package com.demo;
/**
* 传说,Tango有一大“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。
* 如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的ID也在表中,你能快速找出这个传说中的Tango水王吗?
* @author ying
*
*/
public class WaterLead {
/**
* 最直接的方法,我们可以对所有id排序,然后再扫描一遍排好序的Id列表,统计各个id出现的次数。如果摸个id出现的次数
* 操作总数的一半,那么久输出这个id。这个算法的时间复杂度为O(N*log2N + N)。
* 如果id列表已经是有序的,还需要扫描一遍整个列表来统计各个id出现的次数吗?
* 如果一个id出现的次数超过总数N的一半。那么,无论水王的id是什么,这个有序的id列表中的第N/2项(从0开始编号)一定
* 会是这个id。不比再次扫描列表。如果能够迅速定位到列表的某一项,除去排序的时间复杂度,后处理需要的时间为O(1)。
* 但是上面两种方法都需要对id列表进行排序,时间复杂度方面没有本质的改进。能否避免排序呢?
* 如果每次删除两个不同的id(不管是否包含“水王”的id),那么,在剩下的id列表中,“水王”id出现的次数仍然超过总数的
*一半。可以通过不断重复这个过程,把id列表中的id总数降低(转化为更小的问题),从而得到答案。新的思路,避免了排序这个
*耗时的步骤,总的时间复杂度只有O(N),且只需要常数的额外内存。
* @param id
* @param n
* @return这个超级水王的id是candidate
*/
public String findWaterLead(int[] id,int n){
for(int i = 0 ;i < n ;i++){
System.out.print(id[i]+",");
}
System.out.println();
System.out.println(n);
int candidate = 0;
int nTimes,i;
for(i = nTimes = 0;i < n;i++){
if(nTimes == 0){
candidate = id[i];
nTimes = 1;
}else{
if(candidate == id[i])
nTimes++;
else
nTimes--;
}
}
return "这个超级水王的id是"+candidate;
}
}
/**
* 传说,Tango有一大“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。
* 如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的ID也在表中,你能快速找出这个传说中的Tango水王吗?
* @author ying
*
*/
public class WaterLead {
/**
* 最直接的方法,我们可以对所有id排序,然后再扫描一遍排好序的Id列表,统计各个id出现的次数。如果摸个id出现的次数
* 操作总数的一半,那么久输出这个id。这个算法的时间复杂度为O(N*log2N + N)。
* 如果id列表已经是有序的,还需要扫描一遍整个列表来统计各个id出现的次数吗?
* 如果一个id出现的次数超过总数N的一半。那么,无论水王的id是什么,这个有序的id列表中的第N/2项(从0开始编号)一定
* 会是这个id。不比再次扫描列表。如果能够迅速定位到列表的某一项,除去排序的时间复杂度,后处理需要的时间为O(1)。
* 但是上面两种方法都需要对id列表进行排序,时间复杂度方面没有本质的改进。能否避免排序呢?
* 如果每次删除两个不同的id(不管是否包含“水王”的id),那么,在剩下的id列表中,“水王”id出现的次数仍然超过总数的
*一半。可以通过不断重复这个过程,把id列表中的id总数降低(转化为更小的问题),从而得到答案。新的思路,避免了排序这个
*耗时的步骤,总的时间复杂度只有O(N),且只需要常数的额外内存。
* @param id
* @param n
* @return这个超级水王的id是candidate
*/
public String findWaterLead(int[] id,int n){
for(int i = 0 ;i < n ;i++){
System.out.print(id[i]+",");
}
System.out.println();
System.out.println(n);
int candidate = 0;
int nTimes,i;
for(i = nTimes = 0;i < n;i++){
if(nTimes == 0){
candidate = id[i];
nTimes = 1;
}else{
if(candidate == id[i])
nTimes++;
else
nTimes--;
}
}
return "这个超级水王的id是"+candidate;
}
}