Dota2 参议院

难度:中等

Dota2 的世界里有两个阵营:Radiant(天辉)和 Dire(夜魇)

Dota2 参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2 游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每一轮中,每一位参议员都可以行使两项权利中的 一 项:

  • 禁止一名参议员的权利:参议员可以让另一位参议员在这一轮和随后的几轮中丧失 所有的权利
  • 宣布胜利:如果参议员发现有权利投票的参议员都是 同一个阵营的 ,他可以宣布胜利并决定在游戏中的有关变化。

给你一个字符串 senate 代表每个参议员的阵营。字母 'R''D'分别代表了 Radiant(天辉)和 Dire(夜魇)。然后,如果有 n 个参议员,给定字符串的大小将是 n

以轮为基础的过程从给定顺序的第一个参议员开始到最后一个参议员结束。这一过程将持续到投票结束。所有失去权利的参议员将在过程中被跳过。

假设每一位参议员都足够聪明,会为自己的政党做出最好的策略,你需要预测哪一方最终会宣布胜利并在 Dota2 游戏中决定改变。输出应该是 “Radiant” 或 “Dire” 。

示例 1:

输入:senate = "RD"
输出:"Radiant"
解释:
第 1 轮时,第一个参议员来自 Radiant 阵营,他可以使用第一项权利让第二个参议员失去所有权利。
这一轮中,第二个参议员将会被跳过,因为他的权利被禁止了。
第 2 轮时,第一个参议员可以宣布胜利,因为他是唯一一个有投票权的人。

示例 2:

输入:senate = "RDD"
输出:"Dire"
解释:
第 1 轮时,第一个来自 Radiant 阵营的参议员可以使用第一项权利禁止第二个参议员的权利。
这一轮中,第二个来自 Dire 阵营的参议员会将被跳过,因为他的权利被禁止了。
这一轮中,第三个来自 Dire 阵营的参议员可以使用他的第一项权利禁止第一个参议员的权利。
因此在第二轮只剩下第三个参议员拥有投票的权利,于是他可以宣布胜利

贪心 + 「循环」队列

思路:
我们以天辉方的议员为例。当一名天辉方的议员行使权利时:

  • 如果目前所有的议员都为天辉方,那么该议员可以直接宣布天辉方取得胜利;
  • 如果目前仍然有夜魇方的议员,那么这名天辉方的议员只能行使「禁止一名参议员的权利」这一项权利。显然,该议员不会令一名同为天辉方的议员丧失权利,所以他一定会挑选一名夜魇方的议员。那么应该挑选哪一名议员呢?容易想到的是,应该贪心地挑选按照投票顺序的下一名夜魇方的议员。这也是很容易形象化地证明的:既然只能挑选一名夜魇方的议员,那么就应该挑最早可以进行投票的那一名议员;如果挑选了其他较晚投票的议员,那么等到最早可以进行投票的那一名议员行使权利时,一名天辉方议员就会丧失权利,这样就得不偿失了。

由于我们总要挑选投票顺序最早的议员,因此我们可以使用两个队列 r_quene \textit{r\_quene} r_quene 和 d_quene \textit{d\_quene} d_quene 分别按照投票顺序存储天辉方和夜魇方每一名议员的投票时间。随后我们就可以开始模拟整个投票的过程:

  • 如果此时 r_quene \textit{r\_quene} r_quene 或者 d_quene \textit{d\_quene} d_quene 为空,那么就可以宣布另一方获得胜利;
  • 如果均不为空,那么比较这两个队列的首元素,就可以确定当前行使权利的是哪一名议员。如果 r_quene \textit{r\_quene} r_quene 的首元素较小,那说明轮到天辉方的议员行使权利,其会挑选 d_quene \textit{d\_quene} d_quene 的首元素对应的那一名议员。因此,我们会将 d_quene \textit{d\_quene} d_quene 的首元素永久地弹出,并将 r_quene \textit{r\_quene} r_quene 的首元素弹出,增加 n 之后再重新放回队列,这里 n 是给定的字符串 senate \textit{senate} senate 的长度,即表示该议员会参与下一轮的投票。同理,如果 d_quene \textit{d\_quene} d_quene 的首元素较小,那么会永久弹出 r_quene \textit{r\_quene} r_quene 的首元素,剩余的处理方法也是类似的。

这样一来,我们就模拟了整个投票的过程,也就可以得到最终的答案了

时间复杂度: O ( n ) O(n) O(n),其中 n n n 是字符串 senate \textit{senate} senate 的长度。在模拟整个投票过程的每一步,我们进行的操作的时间复杂度均为 O ( 1 ) O(1) O(1),并且会弹出一名天辉方或夜魇方的议员。由于议员的数量为 n n n,因此模拟的步数不会超过 n n n,时间复杂度即为 O ( n ) O(n) O(n)。
空间复杂度: O ( n ) O(n) O(n),即为两个队列需要使用的空间。

import collections
class Solution:def predictPartyVictory(self, senate: str) -> str:length = len(senate)r_quene, d_quene = collections.deque(), collections.deque()for i, x in enumerate(senate):if x == 'R':r_quene.append(i)else:d_quene.append(i)while r_quene and d_quene:r, d = r_quene.popleft(), d_quene.popleft()if r < d:r_quene.append(r + length)else:d_quene.append(d + length)return "Radiant" if r_quene else "Dire"

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/dota2-senate

算法刷题打卡第43天:Dota2 参议院相关推荐

  1. 算法刷题打卡第34天:有效的井字游戏

    有效的井字游戏 难度:中等 给你一个字符串数组 b o a r d board board 表示井字游戏的棋盘.当且仅当在井字游戏过程中,棋盘有可能达到 b o a r d board board 所 ...

  2. 算法刷题打卡第63天:对称二叉树

    对称二叉树 难度:简单 给你一个二叉树的根节点 root , 检查它是否轴对称. 示例 1: 输入:root = [1,2,2,3,4,4,3] 输出:true 示例 2: 输入:root = [1, ...

  3. 算法刷题打卡第76天:判断矩阵是否是一个 X 矩阵

    判断矩阵是否是一个 X 矩阵 难度:简单 如果一个正方形矩阵满足下述 全部 条件,则称之为一个 X 矩阵 : 矩阵对角线上的所有元素都 不是 0 矩阵中所有其他元素都是 0 给你一个大小为 n x n ...

  4. 算法刷题打卡第70天:强密码检验器 II

    强密码检验器 II 难度:简单 如果一个密码满足以下所有条件,我们称它是一个 强 密码: 它有至少 8 个字符. 至少包含 一个小写英文 字母. 至少包含 一个大写英文 字母. 至少包含 一个数字 . ...

  5. 算法刷题打卡第11天:合并两个有序数组

    合并两个有序数组 难度:简单 给你两个按非递减顺序排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目. 请你合并 nums2 到 ...

  6. 算法刷题-数论-试除法求约数、约数个数、约数之和、最大公约数(辗转相除法)

    文章目录 acwing869. 试除法求约数 acwing870. 约数个数 acwing871. 约数之和 acwing872. 最大公约数 acwing869. 试除法求约数 acwing869. ...

  7. 找到所有数组中消失的数字_【一点资讯】千万程序员的呼声:面试如何拿到大厂Offer?这份阅读量超过11W+的算法刷题宝典请你原地查收 www.yidianzixun.com...

    如何才能通过面试拿到大厂Offer? "刷leetcode!" 这是我听到最多的回答! 现在越来越多的人应聘工作时都得先刷个几十百来道题,不刷题感觉都过不了面试. 无论是面测试.算 ...

  8. 力扣 (LeetCode)-对称二叉树,树|刷题打卡

    Github来源:力扣 (LeetCode)|刷题打卡 | 求星星 ✨ | 给个❤️关注,❤️点赞,❤️鼓励一下作者 [已开启]任务一:刷题打卡 * 10 篇 哪吒人生信条:如果你所学的东西 处于喜欢 ...

  9. 第一届LeetCode刷题打卡赢现金活动开始啦,助力每一位想拿大厂offer的小伙伴!

    大家好,我是路飞!第一届leetcode(剑指Offer.LeetCode Top100)刷题打卡活动即将开始啦 (助力大厂Offer收割机)~ 活动形式: LeetCode刷题在自己的CSDN博客上 ...

最新文章

  1. python2:function
  2. BZOJ 4567 [SCOI2016]背单词 (Trie树、贪心)
  3. C# 使用Timer控件设置时间间隔
  4. io_uring vs epoll ,谁在网络编程领域更胜一筹?
  5. 用new创建一个二维数组,有两种方法,是等价的
  6. python画简便的图-最适合小白学的花色玩Python折线图|画个天气预报
  7. 曼联刷新132年队史纪录
  8. cassandra 学习笔记(2)
  9. 12.统计 日志 ip
  10. 启动kafka时报错:java.nio.file.FileSystemException,另一个程序正在使用此文件,进程无法访问。
  11. 移动应用众包测试综述
  12. 大脑信息编码_编码人大脑的5大小吃
  13. 百度地图api将可视区域定位到当前所在位置
  14. 基于芯科Host-NCP解决方案的Zigbee 3.0 Gateway技术研究(-)-Z3GatewayHost应用
  15. 罗杨老师带你了解谷歌编程之夏(GSoC)活动全流程
  16. 一师一优课计算机课程,教育部一师一优课在线会客室在南京成功直播
  17. poi对excel进行读取
  18. APP二维码微信扫描后无法下载的问题 微信扫码(扫一扫二维码)下载不了app怎么解决
  19. Ajax上传文件的cache、processdata、contentType属性以及FormData对象的总结
  20. git直接打包下载和使用git clone进行项目拷贝的区别(踩坑贴)

热门文章

  1. 阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
  2. 高数 | 洛必达法则的隐藏细节、广义洛必达法则(分母无穷直接洛必达)使用条件
  3. 【解决方案】【亲测有效】Windows10离线安装.net3.5
  4. 5G 时代,优酷推出的帧享究竟是什么?
  5. flex 随机数产生方法
  6. tableau常规操作
  7. 边云协同的优点_边缘计算的云边协同
  8. C++ sort排序函数用法
  9. wait和notify方法
  10. (Anroid Studio)用简单代码实现BMI计算器并且将应用安装到手机上