题目地址:https://leetcode.com/problems/dota2-senate/description/

题目描述:

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

TheDota2 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、 Banonesenator'sright:Asenatorcanmakeanothersenatorloseallhisrightsinthisandallthefollowingrounds.;
2、 Announcethevictory:Ifthissenatorfoundthesenatorswhostillhaverightstovoteareallfromthesameparty,hecanannouncethevictoryandmakethedecisionaboutthechangeinthegame.Givenastringrepresentingeachsenator'spartybelonging.Thecharacter'R'and'D'representtheRadiantpartyandtheDirepartyrespectively.Theniftherearensenators,thesizeofthegivenstringwillben.;

Theround-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、 Thelengthofthegivenstringwillintherange[1,10,000].;

题目大意

模拟Dota2参议院的获胜规则。题目比较长,简言之就是,有两个角色R和D,每个角色每轮投票都可以ban掉另外一个角色,这个操作一直做下去,直到最后能发言的只是一种角色,那么这类角色就赢了。注意哈,已经Ban掉的,不能投票了。

解题方法

看到长度范围是10000,估计只能用时间复杂度O(N)的算法了,但是没想到遍历一遍能怎么做,所以看了别人的方法,还真是模拟这个过程,直至获胜为止。

方法其实还是很简单的,模拟这个过程使用的是两个队列的贪心算法,这个方法是每次只杀掉下一个要发言的对方的参议员。即先把每个角色出现的位置都分别进入各自的队列,然后两个队列都从头pop出来,然后比较一下谁能活下来,然后放到这个队列的最后去。用了一个+n的技巧,来说明是这轮已经结束的,给下轮作比较。这个步骤比较重要,如果不+n那么这个元素相等于在这一轮投票中一直投票。

这个时间复杂度不好分析,但假设R和D的数量大致相等的话,那么一轮过后,基本剩下的个数就不多了,所以平均的时间复杂度是O(N),空间复杂度是O(N).

代码如下:

class Solution(object):
    def predictPartyVictory(self, senate):
        """
        :type senate: str
        :rtype: str
        """
        q_r, q_d = collections.deque(), collections.deque()
        n = len(senate)
        for i, s in enumerate(senate):
            if s == "R":
                q_r.append(i)
            else:
                q_d.append(i)
        while q_r and q_d:
            r = q_r.popleft()
            d = q_d.popleft()
            if r < d:
                q_r.append(r + n)
            else:
                q_d.append(d + n)
        return "Radiant" if q_r else "Dire"

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

参考资料:

https://leetcode.com/problems/dota2-senate/discuss/105858/JavaC++-Very-simple-greedy-solution-with-explanation

DDKK.COM 弟弟快看-教程,程序员编程资料站,版权归原作者所有

本文经作者:负雪明烛 授权发布,任何组织或个人未经作者授权不得转发