【编程之美】读书笔记:寻找发帖水王

编程之美: 第二章 数字之魅 2.3_1寻找发帖超过总帖1/4的水王 /* 有3个发帖很多的ID,他们发帖数目都超过了帖子总数目N的1/4,你能从ID列表中找出它们的ID吗? 先考虑2个发帖很多的ID,他们发帖数目超过帖子总数目的1/3,每次删除三个不一样的便可 输入:(针对2两个水王) 9 1 2 3 2 3 2 3 2 3 输出: 2 3 输入:(针对3个水王) 16 1 2 3 4 2 3 4 2 3 4 2 3 4 2 3 4 输出: 2 3 4 */ 阅读详情

       问题:传说,Tango有一大“水王”,他不但喜欢发帖还会回复其他ID发的每个帖子。该“水王”的帖子数目超过了帖子总数的一半,如何用快速的方法找出这个“水王”的ID?

         分析:首先想到的是对所有的ID进行排序,然后再扫描一遍排好序的ID列表,统计各个ID出现的次数。如果某个ID的次数超过总数的一半,那么就输出这个ID。这个算法的时间复杂度为O(N*logN+N).

               如果ID列表是已经排好序,则不需要重复扫描整个列表了。如果一个ID出现的次数超过总数N的一半。那么无论水王的ID是什么,这个有序的ID列表的第N/2 项(从0开始编号)一定会是这个水王的ID。出去排序的的时间复杂度,后处理需要的时间为O(1)。

             但是上面两个方法都需要先对ID列表进行排序,时间复杂度方面没有本质的改变。能否避免排序呢?

             如果每次删除两个不同的ID(不管是谁的ID),那么,在剩下的ID列表中,“水王”的ID出现的次数仍然超过总数的一半。按照这个原理,就可以不断重复这个过程,把ID列表中的ID总数降低,从而得到问题的答案。这个算法的时间复杂度只需要O(N),并且只需要常数的额外内存。

          算法实现: 数组中有个数字出现的次数超过了数组长度的一半。也就是说,有个数字出现的次数比其他所有数字出现次数的和还要多。因此我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字,一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1。 如果下一个数字和我们之前保存的数字不同,则次数减1。如果次数为零,我们需要保存下一个数字,并把次数重新设为1。  
        下面,举二个例子:

  • 第一个例子,5,5,5,5,1 :

    不同的相消,相同的累积。遍历到第四个数字时,candidate 是5, nTimes 是4;    遍历到第五个数字时,candidate 是5, nTimes 是3;  nTimes不为0,那么candidate就是超过半数的。 

  • 第二个例子,0,1,2,1,1:

    开始时,保存candidate是数字0,ntimes为1,遍历到数字1后,与数字0不同,则ntime减1变为零,;接下来,遍历到数字2,2与1不同,candidate保存数字2,且ntimes重新设为1;继续遍历到第4个数字1时,与2不同,ntimes减一为零,同时candidate保存为1;最终遍历到最后一个数字还是1,与我们之前candidate保存的数字1相同,ntime加一为1。最后返回的是之前保存的candidate为1

 

代码如下:

 int Find(int * ID, int N)
{
int  candidate;
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 candidate;
}

例如:a[]={0,4,4,1,4,4,5,4},输出为4。

 

扩展问题:若三个发帖很多的ID,他们的发帖数目都超过了帖子总数目N的1/4,怎么从发贴的ID中快速找出他们的ID?

typedef int Type;
Type candidate1 ;
Type candidate2;
Type candidate3;

void Find(Type* ID, int N)
{
    int nTimes1 = 0 ;
    int nTimes2 = 0 ;
    int nTimes3 = 0 ;
    int i;

    for( i = 0; i < N; i++)
    {
        if (nTimes1 == 0)
        {
            candidate1 = ID[i],nTimes1 = 1;
        }
        else
        {
            if (candidate1 == ID[i])
            {
                nTimes1++;
            }
            else
                if (nTimes2 == 0)
                {
                    candidate2 = ID[i],nTimes2 = 1;
                }
                else
                {
                    if (candidate2 == ID[i])
                    {
                        nTimes2++;
                    }
                    else
                    {
                        if (nTimes3 == 0)
                        {
                            candidate3 = ID[i], nTimes3 = 1;
                        }
                        else
                            if (candidate3 == ID[i])
                            {
                                nTimes3++;
                            }
                            else
                            {
                                nTimes1--;
                                nTimes2--;
                                nTimes3--;
                            }
                    }
                }
        }
    }
}

int main()
{
    int a[] = {0,4,1,4,0,4,1,4,1,0,3,3,0,3,3,3};
    Find(a,16);
    cout << candidate1 <<" " << candidate2 << " " << candidate3 << endl;
    return 0;
}


 

《编程之美》——读书笔记 最近花了几天时间把《编程之美》这本书好好读了一遍,感觉收获还是挺大的。 于是决定做个笔记,算是简单的摘录一些书中的精彩思想,也算重新回顾思考下   1.5 快速找出机器故障 问题描述: 有很多的ID(可能位数很大),其中只有一个ID出现的次数小于2,其他正常ID出现的次数都等于2,求这个次数为1的ID 精彩解法: 将所有的数从头到尾异或一遍,这样得出来的最终结果就是所求的答案。 拓 阅读详情

相关推荐

寻找发帖水王

寻找发帖水王 题目: Tango是微软亚洲研究院的一个试验项目。研究院的员工和实习生们都很喜欢在Tango上面交流灌水。传说,Tango有一大“水王”,他不但喜欢发贴,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的ID也在表中,你能快速找出这个传说中的Tango水王吗?

算法学习十八----寻找发帖水王

题目:经常在论坛或者讨论区上面会看到一些人每个帖子都回复或者发了很多帖子(但是没有对其他用户有用途的)。现在写一个算法,找出发帖数目超过帖子总数的一半的用户ID--称为发帖水王。(注:本题假设发帖水王存在) 算法思路如下: 先对序列排序之后,计算出每个ID的次数,输出出现次数最大的用户ID即可。但是这个方法效率比较低。另一种方法,就是想办法将大问题转换成小问题,对列表进行扫描,每次删除

yipiankongbai的专栏 1480

告别手绘!用Aseprite+Unity Tilemap,从AI生成到2D游戏地图的保姆级搭建流程

本文详细介绍了如何利用Aseprite和Unity Tilemap从AI生成素材到搭建2D游戏地图的完整流程。涵盖AI生成素材的预处理、图层管理、动画制作,以及Unity中的Tilemap系统配置和性能优化技巧,帮助开发者高效创建像素风游戏地图。

weixin_29015483的博客 580

寻找发帖“水王“(分治法)

寻找发帖"水王";分治法;O(n)

freeline的博客 1508

学术报告系列(二) - 智能自主作业机器人感知与控制技术及发展趋势

收集整理于2022年模式识别高峰论坛湖南大学王耀南院士报告(报名题目:智能自主作业机器人感知与控制技术及发展趋势)

Make something people want. 4696

soul聊天协议逆向

通过观察上面的CFG发现,该混淆符合以下逻辑,整体思路就是先查找主分发器,一般被引用次数最多的那个块就是主分发器,引用主分发器的块大概率是真实块,再使用unicorn模拟执行,遍历每一个分支,记录每一个块,如果某一个块是上次记录的块则也为真实块,无后继的块则为retn块,剩下的就是无用块。通过Frida Hook libc.so后发现,聊天协议走的是JAVA层的socket,然后Hook JAVA层相关函数得到如下调用堆栈。里面调用的函数不是很多,所以。不行不行,革命要彻底!

2503_90751789的博客 3207

数字之魅——寻找发帖水王

寻找发帖水王这个题目给了我很大的启发,同时开阔了视野,往往在解决这类型问题的时候第一想法都是先排序再计算。而本题却给出了一个非常好的思路,时间复杂度为O(N)。它还有一个扩展问题,但是我在网上看了几篇有的写的考虑不周全,有的写的逻辑不是很清楚,这里我也根据思考和查阅,给出我自己的解法。typedef int Type; //给出Id的一个抽象 Type candidate[3] = {0}; //说

奔跑的小河 877

PCIE Lane Margining Linux 环境配置

Copy all the provided files in folder PYC38 or PYC310 to the created pcie_lmt folder. Index of /ftp/python/3.8.10/Copy below commands to a file and rename it as "scan_pcie.py", the commands are from "685662 PCIe-LMT-Gen4_Gen5-r0p77.pdf" in the lane margi

mysongshine的博客 1435

《编程之美》读书笔记: 寻找发帖水王的扩展题

最近,零零散散的看了《编程之美》这本书的一两道题,发现都是挺有趣的题目,书里面的思路很好,看完后启发真不少,其中有一道叫“寻找发帖水王”的题目,用一般思路去解决,时间复杂度会是O(N * log2N + N)。但换一种简单的思路却可以是O(N),这对程序来说,在运行效率上应该是质的飞跃了。原题目如下:http://www.msra.cn/Articles/ArticleItem.aspx?Gu

zhong317的专栏 5027

【YOLOv11改进- 主干网络】YOLOv11+WTConv(ECCV2024): 基于YOLOv11的主干网络改进,大感受野的小波卷积

论文提出了WTConv,这是一个使用级联小波分解的层,并执行一组小卷积核的卷积,每个卷积专注于输入的不同频率带,并具有越来越大的感受野。这个过程能够在输入中对低频信息给予更多重视,同时仅增加少量可训练参数。实际上,对于一个  的感受野,可训练参数数量只随着  的增长而呈对数增长。而WTConv与常规方法的参数平方增长形成对比,能够获得有效的卷积神经网络(CNN),其有效感受野(ERF)大小前所未有。

qq_41304809的博客 1401

PCL Trimmed ICP实现点云精配准【2025最新版】

博客长期更新,本文最新更新时间为:2025年6月25日。抄袭狗记得来抄最新代码哦,抄都抄成错的,不够丢人钱。

点云侠的博客 37万+

《编程之美》读书笔记: 寻找发帖水王的扩展问题 2.3

<br />随着Tango的发展,管理员发现,“超级水王”没有了。统计结果表明,有3个发帖很多的ID,他们的发帖数目都超  过了帖子总数目N的1/4。你能从发帖ID列表中快速找出他们的ID吗? <br /> <br />int a[] = {7,1,1,1,1,1,3,2,3,2,3,2,3,2,3,2,3,2,1,9}; vector<int> vi(a,a+20); int aTimes=0; int bTimes=0; int cTimes=0; int aCur=0; int

韧 4089

Linux 命令行的艺术

Linux 命令行的艺术前言基础日常使用文件及数据处理系统调试单行脚本冷门但有用仅限 OS X 系统仅限 Windows 系统更多资源免责声明熟练使用命令行是一种常常被忽视,或被认为难以掌握的技能,但实际上,它会提高你作为工程师的灵活性以及生产力。本文是一份我在 Linux 上工作时,发现的一些命令行使用技巧的摘要。有些技巧非常基础,而另一些则相当复杂,甚至晦涩难懂。这篇文章并不长,但当你能够熟练...

AI天才研究院 9278

编程之美--寻找发帖水王

问题描述: Tango是微软亚洲研究院的一个试验项目。研究院的员工和实习生们都很喜欢在Tango上面交流灌水。传说,Tango有一大“水王”,他不但喜欢发贴,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。如果你有一个当前论坛上所有帖子(包括回帖)

rein07的专栏 1万+

基于matlab的主成分分析的人脸二维码识别系统

人脸识别因其在系统安全验证、信用验证、刑侦跟踪、身份管理、视频会议、人机交互、智能家居等方面的巨大应用前景,成为当前模式识别和人工智能领域越来越热门的一个研究方向。随着安全入口控制和二维码智能扫描应用需求的快速增长,基于二维码识别的生物人脸统计识别技术也引起了人们的重视。本案例将详细讲解基于主成分分析的人脸特征提取的原理与方法,并将其与 QR 二维码的编解码进行结合,将 MATLAB 作为工具平台,调用 QR 二维码编解码应用程序,进而实现一个人脸二维码自动识别的系统原型。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 976

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

编程之美----寻找发帖水王

编程之美----寻找发帖水王 题目:Tango是微软亚洲研究院的一个试验项目。研究院的员工和实习生们都很喜欢在Tango上面交流灌水。传说,Tango有一大“水王”,他不但喜欢发贴,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的ID也在表中,你能快速找出这个传说中的Tango水王吗? –《

chenglinhust的专栏 8411

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

编程之美 寻找发帖水王 扩展问题

编程之美中的“寻找发帖水王”描述的是这么一个问题,有一个ID列表,其中有一个ID(水王的ID)出现的次数超过了一半,请找出这个ID。 书中的思路是每次从列表中删除两个不同的ID,不影响“水王的ID在剩余ID中仍然超过一半”这一事实,因此每次删除两个不同的ID,直到剩下的所有ID都相同,那么剩下的就是水王的ID。 具体编程的时候,使用一个candidate记录当前猜测的水王ID,一个count记

super_chris的专栏 1万+

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

编程之美之寻找发帖水王

简单来说就是求一个数组中出现次数超过一半的次数的数(保证存在),最容易想到的就是先排序,再返回中间位置的值。 优化方式就是每次删去两个不相等的数,最后找不到不相等的数,那么最后剩下的数就是这个出现次数超过一半的数。 考虑到每次寻找两个不相等的数比较困难,我们可以借助种思想换种写法。 用candidate代表当前候选的数,time次数,从头往后遍历,如果出现一次就time+1,不相等就time

fengsigaoju的博客 976

编程之美 -- 寻找发帖水王,以及扩展题

#include #include using namespace std; unsigned int find_id(unsigned int *array,unsigned int n); unsigned int find_half_id(unsigned int *array,unsigned int n); void find_3_more(unsigned int *array,

点滴在心 888

寻找发帖水王java_编程之美之寻找发帖水王

简单来说就是求一个数组中出现次数超过一半的次数的数(保证存在),最容易想到的就是先排序,再返回中间位置的值。优化方式就是每次删去两个不相等的数,最后找不到不相等的数,那么最后剩下的数就是这个出现次数超过一半的数。考虑到每次寻找两个不相等的数比较困难,我们可以借助种思想换种写法。用candidate代表当前候选的数,time次数,从头往后遍历,如果出现一次就time+1,不相等就time-1如果ti...

weixin_42501848的博客 218

发帖水王

关于发帖水王的求解,第一种解法是编程之美上的解法,第二种解法是寻找中位数,因为中位数必然超过一半,两种解法这里不再做解答 扩展问题很好,有3个发帖很多的ID,他们的发帖数量都超过了帖子总数目N的1/4,找出他们的ID #include using namespace std; int array[] = {1, 2, 1, 1, 2, 3, 2, 2, 3, 3, 1, 3, 4, 5,

alexingcool的专栏 8691

寻找发帖水王java_编程之美–寻找发帖水王 | Acm之家

问题描述:Tango是微软亚洲研究院的一个试验项目。研究院的员工和实习生们都很喜欢在Tango上面交流灌水。传说,Tango有一大“水王”,他不但喜欢发贴,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的ID也在表中,你能快速找出这个传说中的Tango水王吗?书中第一种方法是先对ID进行排序,再遍历排序后...

weixin_35369702的博客 204

【算法练习】寻找水王

【来源】编程之美 【】问

张小牙的博客 1351

《编程之美》寻找发帖水王 质疑

《编程之美》一书上关于发帖水王的解答请参见点击打开链接。但是该算法求解的答案并不符合题意,当前求解的答案只是候选者,绝不是真正的发帖水王。比如,输入:{1,2,3,4,5,6,7,87,8,9,10,11,11},输出:11.此时很直观可以确认id=11的作者不是发帖水王。书上给出的算法求解的只是候选者后,应再进行一遍遍历计数,确定个数确实大于总个数的一半,才能被认为是发帖水王。

lingyuan_zhu的博客 480
上一篇: 【编程之美】读书笔记:给定一个整数N,求N!末尾有多少个0
下一篇: 【编程之美】读书笔记:求1到N之间整数中出现1的个数
xiaoding133
博客等级 码龄19年 415粉丝 159原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值