美文网首页
超级水王问题

超级水王问题

作者: xdm | 来源:发表于2021-07-16 00:08 被阅读0次

问题描述
假设有一个数组,如果数组中的某一项出现的次数大于数组长度的一半,则这一项就是水王?

可能是因为帖子评论区一半以上的评论都出自于某个用户,表示这个用户一直在灌水吧

问题分析

  • 要求时间复杂度是O(n)
  • 空间复杂度控制在O(1)
    如果遍历时使用map统计每一项出现的次数,最坏的空间复杂度很显然是O(n)

解题思路
根据题目,如果水王存在的话,水王的个数是大于数组长度的一半,那么如果把数组中任意两个不相同的项同时消除的话,很显然水王不会被全部消除(但是反过来,是不一定成立的,大家可以想一下为什么?)。
现在问题变成怎样消除数组中一对不同的项,很多人可能想到了使用栈,依次遍历数组,如果栈为空,则进行入栈操作,如果站不为空,判断当前遍历的值与栈底的值是不是想等,如果相等则进行入栈操作,如果不想等则进行出栈操作,最后判断栈中的值,大家可以想一想,这样做对吗?
很显然上面使用栈来操作消除数组中一对不同的项的操作违反了空间复杂度为O(1)的原则,那么该怎样消除呢?
现在提出一个血量的概念,这个血量就可以看作剩余水王的数量,初始将血量设置为0,水王设置为None,遍历数组,判断血量是否为0?

  • 如果血量为0,则设置水王为当前遍历出的值
  • 如果血量不为空,则判断当前遍历的值和水王的值是否相等
    • 如果想等,则血量加1
    • 如果不想等,则血量减1
  • 最后判断判断血量是否为0,如果为0,则肯定不存在水王,如果不为0,那么则需要再次判断水王的值在数组中出现的次数(为什么?[1, 2, 3, 4, 5])。

这样做就可以保证空间复杂度为O(1),代码实现如下:

def super_water_king(arr):
    """ 超级水王问题

    desc: 一个数组中单个项出现的次数大于当前数组长度的一半
    idea: 遍历数组,相邻(当前遍历数字与靶子值相比)两个数字相同则靶子数(即血量)+1,如果相邻的两个数字不相同则靶子数(即血量)-1
          如果血量为0,表示靶子没有了,把当前被遍历的数字设置为靶子,同时血量设置为1,这样使用血量的方式就可以控制靶子的变化或者靶子数的增减
    """

    if not arr:
        return False

    # 先设定当前靶子为空,血量为0
    # 如果血量为0时,表示当前靶子为空,此时需要添加靶子
    # 如果血量不为0:
    #   1、如果当前遍历的值与靶子相同,血量加1
    #   2、如果当前遍历的值与靶子不相同,血量减1
    # 如果遍历完成后,血量为0, 则肯定不存在超级水王数
    # 如果遍历完成后,血量不为0, 要再一次遍历全部数组,计算当前靶子数字出现的次数
    target = None
    curr_hp = 0

    for n in arr:
        if curr_hp == 0:
            target = n
            curr_hp = 1
        elif n != target:
            curr_hp -= 1
        else:
            curr_hp += 1

    if curr_hp == 0:
        return False

    count = 0
    for i in arr:
        if i == target:
            count += 1

    if count > len(arr) >> 1:
        return True

    return False


# Test
for _ in range(10):
    arrs = [random.randint(10, 12) for i in range(10)]
    print(arrs)
    print(super_water_king(arrs))

问题的思考
1、数组中消除同类或者异类的操作是不是可以归结到靶子(水王)血量上来呢?
2、选举中获取一般票数以上的人当选的问题是否也可以归结为水王问题?
3、消除过后如果剩余的血量为0,则不存在水王,但是如果血量不为0,千万别以为水王就存在,这是不成立的。

相关文章

  • 超级水王问题

    问题描述假设有一个数组,如果数组中的某一项出现的次数大于数组长度的一半,则这一项就是水王? 可能是因为帖子评论区一...

  • 一次对话

    杨小羊 青青:昨天我认识到了我一个超级超级劣根的问题。 超级超级肮脏劣根的。。。。 我男友王博有一个室友 找了个女...

  • 超级水更

    今天我连屋子都没出,好厉害 不不出去了两次 那也厉害 反正快开学了,昨天抢的票 终于可以飞石家庄了 咦,怎么才五十...

  • 超级捧场王

    吃过晚饭,两个孩子一个刷鞋子,一个洗碗。 妞妞一边刷鞋一边不着调的乱唱:天空飘来五个字,那都不是事儿!壮壮说:“姐...

  • 超级即兴王

    背景: 即兴训练营举办全民选拔,试问谁是超级即兴王? 海选赛区: 五人剧本,严格执行即兴模型(yes,and和三不...

  • 无标题文章搜索

    问题描述水水水水 如下图,若既是是是满足A列又搜索满足B列条件下,使用Vlookup找出1班王五的成绩。 *此案例...

  • 4.22-4.28事件时间日志

    34.22日:起床6.44,和燕姐客户通话,有点小问题。读《超级版图》7.14-8.00。站桩8.30。水蓝湾等燕...

  • 为了实现两年收入翻 2 倍,我做了一份详细计划,可能对你也有用

    100天写作计划 第54天文/于水水小玩子 写在前面: 真的是特别喜欢古典老师#超级个体每日一问#里的问题,也喜欢...

  • 水王星

    水王星致力于高端饮用水优化,即高端净水器(直饮水机),能够制备或给付纯净水、功能水、温水、热水和冰水等其他用途水的...

  • 水贼王

    ——13岁的疯神bb叨 海贼王是一部多年连载的日漫,我在很小的时候就入坑了,我一直看到现在,但是最...

网友评论

      本文标题:超级水王问题

      本文链接:https://www.haomeiwen.com/subject/hupmpltx.html