查看原文
其他

腾讯三面:你会找半数以上的QQ号码吗?

IT服务圈儿 2023-02-06

The following article is from 涛歌依旧 Author 点击关注👉👉

来源丨经授权转自 涛歌依旧(ID:ai_taogeyijiu_2021)

作者丨涛哥


大家好,我是涛哥。

我们来看一道腾讯三面的面试题目,初看起来是挺简单的,其实不然。题目如下:

有2N个QQ号码,其中有一个QQ号码出现的次数大于N次,请找出这个QQ号码。要求:时空复杂度尽可能低。

有的人看到题目后就开始做,貌似也能得到正确结果,但无法通过腾讯的面试,主要是算法时空复杂度非最优。

涛哥手绘

一.暴力排序

排序是最容易想到的一种方法。由于目标QQ号码出现的次数超过数组长度的一半,所以排序后直接取中间元素就行。

腾讯会出这么简单的题目吗?有点搞笑!我们知道,基于比较的排序,时间复杂度能达到O(NlogN), 但这不是最好的方法,无法通过腾讯的面试


二.计数统计

既然题目的意思是求出这个次数超过一半QQ号码,那就对次数进行计数吧,直接搞个hashmap就行了。此时,时间复杂度是O(N), 但空间复杂度也是O(N),无法通过腾讯的面试

而且要注意到,使用计数法的时候,漏用了题目中的信息:出现次数大于N。显然,这是不合理的。这就跟你高考数学一样,你发现有个条件居然没用到,而你把题目做出来了,那是很值得怀疑的。


三.摩尔投票

接下来,我们来介绍一种很巧妙的思路,即摩尔投票法,时间复杂度是O(N), 空间复杂度是O(1),可以满足腾讯面试的要求。思路是怎样的呢?

为了求超过半数的QQ号码,我们来看一种现实中的投票场景,以投票选择班长为例:

班级要开始选班长

要求半数以上通过

选出来的就是班长

我们先来看一种简单的情况:假如只有2个人A和B竞争班长这一职位。那么,在大家投票后,我们从投票箱中取数后,可以这样统计:

  • 先抽一张票,如果是A,则记录当前胜利者为A,票数:1

  • 再抽一张票,如果是A,则记录当前胜利者为A,票数:2

  • 再抽一张票,如果是B,则抵消,记录当前胜利者为A,票数:1

  • 再抽一张票,如果是B,则抵消,记录无当前胜利者

  • 再抽一张票,如果是A,则记录当前胜利者为A,票数:1

  • ...

如此循环,直到所有票统计完毕,最后有票的一方,就是胜利者,就是大家选出来的班长。这就是所谓的摩尔投票法。


如上只是两方进行PK, 那么,当候选人为多人时,也可以使用类似的思路,这里的前提条件就是:一定存在多余半数票的候选人。

当多方进行PK时,占据着半数以上票数的班长,可以任性地抵消任何人的票,而且其他人之间的相互抵消也不会撼动班长的位置。

有的朋友看到这里,可能觉得有点绕,那么,我们一起来看看程序,并打印关键步骤,有兴趣的朋友可以对照程序和结果理解下。

腾讯主要使用C++编程,所以,我们就用C++来写代码,如下是对应的C++程序代码。solution函数详细地说明了摩尔投票过程:

#include <iostream>using namespace std;
int solution(int a[], int n) {     int count = 0, value = a[0]; for(int i = 0; i < n; i++) { printf("log, i=%d, count=%d, value=%d\n", i, count, value); if(count == 0) { value = a[i]; }
if(a[i] == value) { count++; } else { count--; } }
return value;}

int main(){ int a[]={6,2,5,3,4,2,2,2,2,5}; int n = sizeof(a) / sizeof(a[0]); cout << solution(a, n) << endl; return 0;}

结果如下(经检验无误):

log, i=0, count=0, value=6log, i=1, count=1, value=6log, i=2, count=0, value=6log, i=3, count=1, value=5log, i=4, count=0, value=5log, i=5, count=1, value=4log, i=6, count=0, value=4log, i=7, count=1, value=2log, i=8, count=2, value=2log, i=9, count=3, value=22



好的,先说这么多,希望大家在准备面试时,获得启发,举一反三,融会贯通,有所进步。今天先这样,咱们明天见


1、超越 Nginx!号称下一代 Web 服务器,用起来够优雅!

2、用 Markdown 做的 PPT,真的太强了!

3、函数调用时底层发生了什么?

4、京东二面:高并发设计,都有哪些技术方案?

5、程序员最硬大佬,你绝对想不到!!!

点分享

点点赞

点在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存