python-leetcode-Dota2 参议院

649. Dota2 参议院 - 力扣(LeetCode)

这是一个典型的队列模拟问题,可以使用两个队列分别存储 'R''D' 参议员的索引位置,然后模拟投票过程。下面是解决方案:

思路:

  1. 使用队列存储参议员的位置

    • 遍历 senate,将 'R''D' 分别存入两个队列 radiantdire 中,存储它们的索引位置。
  2. 模拟投票过程

    • 取出 radiantdire 各自的队首元素,比较它们的索引。
    • 较小索引的参议员(在前面出现的)可以投票禁止较大索引的参议员,并且该参议员可以在下一轮重新参与投票(索引+n,表示下一轮)。
    • 被禁止的参议员则从游戏中移除(不再加入队列)。
  3. 循环进行投票,直到某个队列为空

    • 如果 radiant 为空,返回 "Dire"
    • 如果 dire 为空,返回 "Radiant"

代码:

from collections import deque

def predictPartyVictory(senate: str) -> str:
    n = len(senate)
    radiant = deque()
    dire = deque()

    # 将 R 和 D 的索引分别存入队列
    for i, s in enumerate(senate):
        if s == 'R':
            radiant.append(i)
        else:
            dire.append(i)

    # 轮流投票
    while radiant and dire:
        r_index = radiant.popleft()
        d_index = dire.popleft()

        # 较小索引的参议员可以继续存活,并将在下一轮投票
        if r_index < d_index:
            radiant.append(r_index + n)  # Radiant 获胜,放回队列
        else:
            dire.append(d_index + n)  # Dire 获胜,放回队列

    # 如果 Radiant 队列还有人,则 Radiant 获胜,否则 Dire 获胜
    return "Radiant" if radiant else "Dire"

复杂度分析:

  • 遍历字符串初始化队列:O(n)
  • 由于每个参议员最多被投票一次,每轮都会淘汰一个人,因此最多 O(n) 轮。
  • 由于队列操作是 O(1),整个算法的时间复杂度是 O(n)

示例:

print(predictPartyVictory("RD"))       # "Radiant"
print(predictPartyVictory("RDD"))      # "Dire"
print(predictPartyVictory("RRDDD"))    # "Radiant"

这个方法巧妙利用了 队列 进行 模拟,保证每轮都按照索引顺序进行投票,非常高效!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值