「leetcode」649.Dota2 参议院

原题

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

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

禁止一名参议员的权利:bash

参议员可让另外一位参议员在这一轮和随后的几轮中丧失全部的权利。spa

宣布胜利:code

若是参议员发现有权利投票的参议员都是同一个阵营的,他能够宣布胜利并决定在游戏中的有关变化。索引

给定一个字符串表明每一个参议员的阵营。字母 “R” 和 “D” 分别表明了 Radiant(天辉)和 Dire(夜魇)。而后,若是有 n 个参议员,给定字符串的大小将是 n。游戏

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

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

示例 1:it

输入: "RD"
输出: "Radiant"
解释:  第一个参议员来自  Radiant 阵营而且他可使用第一项权利让第二个参议员失去权力,所以第二个参议员将被跳过由于他没有任何权利。而后在第二轮的时候,第一个参议员能够宣布胜利,由于他是惟一一个有投票权的人
复制代码

示例 2:

输入: "RDD"
输出: "Dire"
解释: 
第一轮中,第一个来自 Radiant 阵营的参议员可使用第一项权利禁止第二个参议员的权利
第二个来自 Dire 阵营的参议员会被跳过由于他的权利被禁止
第三个来自 Dire 阵营的参议员可使用他的第一项权利禁止第一个参议员的权利
所以在第二轮只剩下第三个参议员拥有投票的权利,因而他能够宣布胜利
复制代码

注意:

给定字符串的长度在 [1, 10,000] 之间.

思路

在每一轮议会选举时,天灾和近卫的优先策略是禁止临近的对方参议员的权利。

咱们循环全部参议员,并把双方对应的索引,存储到不一样的数组中。

咱们依次比较两个数组中,每一位对应的索引。若是天灾的索引小于近卫的索引,那么会淘汰一名近卫的参议院,反之同理。

若是天灾和近卫的人数不相等。若是天灾的人数大于近卫,咱们会从前淘汰近卫的参议院。反之同理。

当第一次议会循环结束时,咱们重置索引为0,而后重复上述的过程。当有一方人数为0的时候,就能够判断谁得到了议会的选举。

本题也是贪心算法的一种,咱们优先作出对局部最优的策略,优先淘汰对方的参议院。减小对方参议院的数量。

代码

/** * @param {string} senate * @return {string} */
var predictPartyVictory = function(senate) {
    let radiants = []
    let dires = []
    
    let radiantIndex = 0
    let direIndex = 0
    
    for (let i = 0; i < senate.length; i++) {
        if (senate[i] === 'R') {
            radiants.push(i)
        } else {
            dires.push(i)
        }
    }
    
    while (radiants.length && dires.length) {
        
        // 一次循环结束
        if (
            radiants[radiantIndex] === undefined &&
            dires[direIndex] === undefined
        ) {
            radiantIndex = 0
            direIndex = 0
        }
        
        // 若是本次循环中radiants已经结束
        if (
            radiants[radiantIndex] === undefined &&
            dires[direIndex] !== undefined
        ) {
            direIndex += 1
            radiants.shift()
            continue
        }
        
        // 若是本次循环中dires已经结束
        if (
            radiants[radiantIndex] !== undefined &&
            dires[direIndex] === undefined
        ) {
            radiantIndex += 1
            dires.shift()
            continue
        }
        
        // 
        if (dires[direIndex] > radiants[radiantIndex]) {
            radiantIndex += 1
            dires.splice(direIndex, 1)
        } else {
            direIndex += 1
            radiants.splice(radiantIndex, 1)
        }
    }
    
    return radiants.length ? 'Radiant' : 'Dire'
};
复制代码
相关文章
相关标签/搜索