TypechoJoeTheme

Toasobi的博客

Dota2 参议院(队列)

本文最后更新于2023年09月15日,已超过370天没有更新。如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!


这道题一开始我想的是拼人头数,所以用的是栈的方式,下面是错误代码
public String predictPartyVictory(String senate) {
        Stack<Character> stack = new Stack<>();
        char[] chars = senate.toCharArray();
        char head = chars[0];
        stack.push(chars[0]);

        for (int i = 1; i < chars.length; i++) {
            if(!stack.isEmpty() && stack.peek() != chars[i]){
                stack.pop();
            }else{
                stack.push(chars[i]);
            }
        }
        if(!stack.isEmpty()){
            return stack.pop() == 'R' ? "Radiant" : "Dire";
        }else{
            return head == 'R' ? "Radiant" : "Dire";
        }
    }

**

  • 方法一:贪心 + 「循环」队列

**

使用两个队列存储投票顺序模拟投票过程

思路与算法

我们以天辉方的议员为例。当一名天辉方的议员行使权利时:

如果目前所有的议员都为天辉方,那么该议员可以直接宣布天辉方取得胜利;

如果目前仍然有夜魇方的议员,那么这名天辉方的议员只能行使「禁止一名参议员的权利」这一项权利。显然,该议员不会令一名同为天辉方的议员丧失权利,所以他一定会挑选一名夜魇方的议员。那么应该挑选哪一名议员呢?容易想到的是,应该贪心地挑选按照投票顺序的下一名夜魇方的议员。这也是很容易形象化地证明的:既然只能挑选一名夜魇方的议员,那么就应该挑最早可以进行投票的那一名议员;如果挑选了其他较晚投票的议员,那么等到最早可以进行投票的那一名议员行使权利时,一名天辉方议员就会丧失权利,这样就得不偿失了。

由于我们总要挑选投票顺序最早的议员,因此我们可以使用两个队列 radiant 和 dire 分别按照投票顺序存储天辉方和夜魇方每一名议员的投票时间。随后我们就可以开始模拟整个投票的过程:

如果此时 radiant 或者 dire 为空,那么就可以宣布另一方获得胜利;

如果均不为空,那么比较这两个队列的首元素,就可以确定当前行使权利的是哪一名议员。如果 radiant 的首元素较小,那说明轮到天辉方的议员行使权利,其会挑选 dire 的首元素对应的那一名议员。因此,我们会将 dire 的首元素永久地弹出,并将 radiant 的首元素弹出,增加 n 之后再重新放回队列,这里 n 是给定的字符串senate的长度,即表示该议员会参与下一轮的投票。

为什么这里是固定地增加 n ,而不是增加与当前剩余议员数量相关的一个数?读者可以思考一下这里的正确性。

这样一来,我们就模拟了整个投票的过程,也就可以得到最终的答案了。

代码如下:

class Solution {
    public String predictPartyVictory(String senate) {
        int n = senate.length();
        Queue<Integer> radiant = new LinkedList<Integer>();
        Queue<Integer> dire = new LinkedList<Integer>();
        for (int i = 0; i < n; ++i) {
            if (senate.charAt(i) == 'R') {
                radiant.offer(i);
            } else {
                dire.offer(i);
            }
        }
        while (!radiant.isEmpty() && !dire.isEmpty()) {
            int radiantIndex = radiant.poll(), direIndex = dire.poll();
            if (radiantIndex < direIndex) {
                radiant.offer(radiantIndex + n);
            } else {
                dire.offer(direIndex + n);
            }
        }
        return !radiant.isEmpty() ? "Radiant" : "Dire";
    }
}
朗读
赞(0)
评论 (0)