异或的神奇运用——落单的数
题目:有2n+1个数,其中有n对相同的,还有一个落单的与其他都不相同,找出这个数;要求时间复杂度O(n),空间复杂度O(1)。
主流解法:将这2n+1个数全部异或起来,相同的数会抵消掉(与异或的顺序无关),最后得出的结果就是落单的数。
我的解法:一开始扫一遍过去找出数组中的中位数(题目条件可知一定存在);然后以这个数为"基准"进行快排的第一步,即完成后小于等于这个基准的数都在它左边,大于等于的都在右边。这之后呢,如果位于数组中间的不是两个相同的,那说明正中间的这个数就是落单的。如果中间是一对相同的数的话,那就看有这对数分开的左右两个数组,如果哪部分的元素个数是奇数,那么那个落单的数就一定在奇数个数的那一半里;然后再这一部分递归做与前两步相同的操作直至找出落单的数。 总的执行次数为 2(n+n/2+n/4+......n/2^k),是n乘上一个常数,故复杂度是为O(n)的;且没用到额外的数组空间,空间复杂度为O(1)。 这种抖机灵的做法思路应该是不难理解的,但实现起来的话特别是边界处理上挺麻烦的。。。 刚看到这道面试题的时候完全没想到有异或这种位运算能用,,,计算机基础知识太薄弱了。。。=_=
加强版题目:如果有2n+2个数,其中有2个数落单,该如何处理?
解法:假设两个不同的数是a和b,并且a!=b,将2n+2个数异或起来就会得到c=a xor b,并且c不等于0。因此在c的二进制位中找到一个为1的位,可推断在这位上a和b分别为0和1,因此将2n+2个数分为该位位0的组和该位为1的组,然后对这两个组分别使用上面简单版的算法就可以了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)