649-Dota2议会

Description

In the world of Dota2, there are two parties: the Radiant and the Dire.

The Dota2 senate consists of senators coming from two parties. Now the senate wants to make a decision about a change in the Dota2 game. The voting for this change is a round-based procedure. In each round, each senator can exercise one of the two rights:

  1. Ban one senator’s right:
    A senator can make another senator lose all his rights in this and all the following rounds.
  2. Announce the victory:
    If this senator found the senators who still have rights to vote are all from the same party, he can announce the victory and make the decision about the change in the game.

Given a string representing each senator’s party belonging. The character ‘R’ and ‘D’ represent the Radiant party and the Dire party respectively. Then if there are n senators, the size of the given string will be n.

The round-based procedure starts from the first senator to the last senator in the given order. This procedure will last until the end of voting. All the senators who have lost their rights will be skipped during the procedure.

Suppose every senator is smart enough and will play the best strategy for his own party, you need to predict which party will finally announce the victory and make the change in the Dota2 game. The output should be Radiant or Dire.


Example 1:

Input: "RD"
Output: "Radiant"
Explanation: The first senator comes from Radiant and he can just ban the next senator's right in the round 1. 
And the second senator can't exercise any rights any more since his right has been banned. 
And in the round 2, the first senator can just announce the victory since he is the only guy in the senate who can vote.

Example 2:

Input: "RDD"
Output: "Dire"
Explanation: 
The first senator comes from Radiant and he can just ban the next senator's right in the round 1. 
And the second senator can't exercise any rights anymore since his right has been banned. 
And the third senator comes from Dire and he can ban the first senator's right in the round 1. 
And in the round 2, the third senator can just announce the victory since he is the only guy in the senate who can vote.

Note:

  1. The length of the given string will in the range [1, 10,000].

问题描述

在Dota2的世界里, 有两种团体: 辐射和恐怖

Dota的议会由两个团体的成员组成。现在议会想起草一个改变Dota2的决定。对这个改变的投票是按轮进行的。
每轮每个议员可以进行如下两个操作之一:

  1. 禁止一个议员的操作
    一个议员可以禁止另一个议员该轮及接下来的操作
  2. 宣布胜利
    如果议员发现还可以操作的议员全部来自同一个团体,那么他可以宣布胜利,并且决定改变。

给定一个字符串,代表每个议员所属团体。’R’代表辐射,’D’代表恐怖。如果有n个议员,那么字符串的长度为n

投票基于字符串的顺序进行, 从第一个议员开始,直到最后一个议员(注意,字符串代表的是第一轮的顺序)。所有被禁止操作的议员会被跳过

假设每个议员都足够聪明并为自己的团体选择最佳的策略,你需要预测那个团体会胜利, 返回’R’代表辐射会胜利,返回’D’代表恐怖会胜利


问题分析

贪心

对于处于R团体的人来说,若在他之后有D团体的人,那么他必须将Dban掉,否则D会ban掉R团体的人,对于D同样如此

使用people保存D和R的人数,第一个元素为D, 第二个元素为R
使用bans保存D和R被ban掉的人数, 第一个元素为D, 第二个元素为R

遍历senate, 将人放入queue中
遍历queue, 若其对应团体有人被ban掉,那么此人被ban掉, 更新bans和people, 否则, 此人ban掉对立团体的人,更新bans, 将此人放入队列末端
若people中任一元素为0, 代表投票结束, 人数不等于0的那一方胜利


解法

class Solution {
    public String predictPartyVictory(String senate) {
        Queue queue = new LinkedList();
        int[] people = new int[]{0, 0};
        int[] bans = new int[]{0, 0};

        for (char person: senate.toCharArray()) {
            int x = person == 'R' ? 1 : 0;
            people[x]++;
            queue.add(x);
        }

        while (people[0] > 0 && people[1] > 0) {
            int x = queue.poll();
            if (bans[x] > 0) {
                bans[x]--;
                people[x]--;
            } else {
                bans[x ^ 1]++;
                queue.add(x);
            }
        }

        return people[1] > 0 ? "Radiant" : "Dire";
    }
}

你可能感兴趣的:(算法与数据结构,leetcode全解,算法,数据结构,leetcode)