0649. Dota2 参议院【中等】
1. 📝 题目描述
Dota2 的世界里有两个阵营:Radiant(天辉)和 Dire(夜魇)
Dota2 参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2 游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每一轮中,每一位参议员都可以行使两项权利中的 一 项:
- 禁止一名参议员的权利:参议员可以让另一位参议员在这一轮和随后的几轮中丧失 所有的权利。
- 宣布胜利:如果参议员发现有权利投票的参议员都是 同一个阵营的,他可以宣布胜利并决定在游戏中的有关变化。
给你一个字符串 senate 代表每个参议员的阵营。字母 'R' 和 'D'分别代表了 Radiant(天辉)和 Dire(夜魇)。然后,如果有 n 个参议员,给定字符串的大小将是 n。
以轮为基础的过程从给定顺序的第一个参议员开始到最后一个参议员结束。这一过程将持续到投票结束。所有失去权利的参议员将在过程中被跳过。
假设每一位参议员都足够聪明,会为自己的政党做出最好的策略,你需要预测哪一方最终会宣布胜利并在 Dota2 游戏中决定改变。输出应该是 "Radiant" 或 "Dire"。
示例 1:
txt
输入:senate = "RD"
输出:"Radiant"
解释:
第 1 轮时,第一个参议员来自 Radiant 阵营,他可以使用第一项权利让第二个参议员失去所有权利。
这一轮中,第二个参议员将会被跳过,因为他的权利被禁止了。
第 2 轮时,第一个参议员可以宣布胜利,因为他是唯一一个有投票权的人。1
2
3
4
5
6
2
3
4
5
6
示例 2:
txt
输入:senate = "RDD"
输出:"Dire"
解释:
第 1 轮时,第一个来自 Radiant 阵营的参议员可以使用第一项权利禁止第二个参议员的权利。
这一轮中,第二个来自 Dire 阵营的参议员会将被跳过,因为他的权利被禁止了。
这一轮中,第三个来自 Dire 阵营的参议员可以使用他的第一项权利禁止第一个参议员的权利。
因此在第二轮只剩下第三个参议员拥有投票的权利,于是他可以宣布胜利1
2
3
4
5
6
7
2
3
4
5
6
7
提示:
n == senate.length1 <= n <= 10^4senate[i]为'R'或'D'
2. 🎯 s.1 - 贪心 + 队列
c
char* predictPartyVictory(char* senate) {
int n = strlen(senate);
int* rq = (int*)malloc(sizeof(int) * n * 2);
int* dq = (int*)malloc(sizeof(int) * n * 2);
int rh = 0, rt = 0, dh = 0, dt = 0;
for (int i = 0; i < n; i++) {
if (senate[i] == 'R') rq[rt++] = i;
else dq[dt++] = i;
}
while (rh < rt && dh < dt) {
int r = rq[rh++], d = dq[dh++];
if (r < d) rq[rt++] = r + n;
else dq[dt++] = d + n;
}
free(rq); free(dq);
return rh < rt ? "Radiant" : "Dire";
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
js
/**
* @param {string} senate
* @return {string}
*/
var predictPartyVictory = function (senate) {
const rQueue = [],
dQueue = []
const n = senate.length
for (let i = 0; i < n; i++) {
if (senate[i] === 'R') rQueue.push(i)
else dQueue.push(i)
}
while (rQueue.length && dQueue.length) {
const r = rQueue.shift(),
d = dQueue.shift()
if (r < d) rQueue.push(r + n)
else dQueue.push(d + n)
}
return rQueue.length ? 'Radiant' : 'Dire'
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
py
class Solution:
def predictPartyVictory(self, senate: str) -> str:
n = len(senate)
r_queue = deque()
d_queue = deque()
for i, c in enumerate(senate):
if c == 'R':
r_queue.append(i)
else:
d_queue.append(i)
while r_queue and d_queue:
r, d = r_queue.popleft(), d_queue.popleft()
if r < d:
r_queue.append(r + n)
else:
d_queue.append(d + n)
return 'Radiant' if r_queue else 'Dire'1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- 时间复杂度:
,其中 n 是参议员数量 - 空间复杂度:
算法思路:
- 用两个队列分别存储 R 和 D 的下标
- 每轮取两队队首比较,下标小的禁用对方并加 n 重新入队(下一轮)
- 某队列为空时,另一方胜出