题号:no649
题目名:Dota2 参议院
原题URL:https://leetcode-cn.com/problems/dota2-senate/
题目描述
Dota2 的世界里有两个阵营:Radiant(天辉)和 Dire(夜魇)
Dota2 参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2 游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每一轮中,每一位参议员都可以行使两项权利中的一项:
禁止一名参议员的权利:
参议员可以让另一位参议员在这一轮和随后的几轮中丧失所有的权利。
宣布胜利:
如果参议员发现有权利投票的参议员都是同一个阵营的,他可以宣布胜利并决定在游戏中的有关变化。
给定一个字符串代表每个参议员的阵营。字母 “R” 和 “D” 分别代表了 Radiant(天辉)和 Dire(夜魇)。然后,如果有 n 个参议员,给定字符串的大小将是 n。
以轮为基础的过程从给定顺序的第一个参议员开始到最后一个参议员结束。这一过程将持续到投票结束。所有失去权利的参议员将在过程中被跳过。
假设每一位参议员都足够聪明,会为自己的政党做出最好的策略,你需要预测哪一方最终会宣布胜利并在 Dota2 游戏中决定改变。输出应该是 Radiant 或 Dire。
示例
示例 1:
输入:"RD"
输出:"Radiant"
解释:第一个参议员来自 Radiant 阵营并且他可以使用第一项权利让第二个参议员失去权力,因此第二个参议员将被跳过因为他没有任何权利。然后在第二轮的时候,第一个参议员可以宣布胜利,因为他是唯一一个有投票权的人
示例 2:
输入:"RDD"
输出:"Dire"
解释:
第一轮中,第一个来自 Radiant 阵营的参议员可以使用第一项权利禁止第二个参议员的权利
第二个来自 Dire 阵营的参议员会被跳过因为他的权利被禁止
第三个来自 Dire 阵营的参议员可以使用他的第一项权利禁止第一个参议员的权利
因此在第二轮只剩下第三个参议员拥有投票的权利,于是他可以宣布胜利
限制
- 给定字符串的长度在
[1, 10,000]
之间.
思路
1.题意就是两个阵容竞争,一个阵容要尽量把他最近的人T出去,循环重复进行投票。
2.贪心算法,尽量把离他最近的人敌方阵容的人T出去
3.注意要记录能够移出去的D和R的数量
解题代码
public class Solution {
//当前位置可以移除D和R的数量
int rmD = 0;
int rmR =0 ;
public String predictPartyVictory(String senate) {
//原则上当前阵容的人一定会将距离他最近的人给干掉
//分别记录天辉和夜魔
int[] count = new int[2];
char[] chars = senate.toCharArray();
for (int i = 0; i < chars.length; i++) {
if(chars[i]=='R') count[0]++;
else count[1]++;
}
while (count[0]!=0&&count[1]!=0) {
check(chars,count);
}
return count[0]==0?"Dire":"Radiant";
}
private void check(char[] chars, int[] count) {
//本次遍历中能删除D和R的次数
for (int i = 0; i < chars.length; i++) {
//如果这个人呗移出去了就不管他
if(chars[i]=='0') continue;
//如果当前位置是R并且前面有D能够把它移出去,那就移出去,否则能够移除D的次数+1
if(chars[i]=='R') {
if(rmR>0) {
rmR--;
chars[i] = '0';
count[0]--;
}else rmD++;
} else {
//当前位置是D同理
if(rmD>0) {
rmD--;
chars[i] = '0';
count[1]--;
}else rmR++;
}
}
}
}