【问题标题】:Winner of the game比赛的获胜者
【发布时间】:2019-10-29 05:04:55
【问题描述】:

我在最近的招聘挑战中遇到了这个问题:

给定N 字符串,每个'0'-'9' 数字和一个整数K。两个玩家 A 和 B 玩游戏如下:

  • A 先播放并选择前K 字符串中的任意字符串。

  • 下一位玩家,B 可以从与上一回合选择的字符串 A 中的最后一个数字相同的数字开始选择字符串,并且在下一个 K 字符串中,直到 A 最后选择的字符串。例如如果 A 选择了索引 i 的“045679”,则 B 只能从索引 i+1i+K 的字符串中选择以数字 '9' 开头的字符串。

  • 挑不出弦的就输了

  • 两个玩家都发挥得很好。

  • 我们需要告诉获胜者以及获胜者拾取的字符串的最小索引。

我以前见过这样的问题,需要关于如何思考这些问题的建议。提前致谢。

【问题讨论】:

    标签: algorithm data-structures dynamic-programming


    【解决方案1】:

    这类似于 nim 游戏。您必须从获胜位置进入失败位置才能仍然获胜。

    我们可以倒退:如果最后一个玩家拿走了最后一根绳子,那么现在要移动的玩家输了,如果捡到了倒数第二个字符串,那么要移动的玩家输了,除非倒数第二个字符串的最后一个数字和最后一个字符串匹配的起始数字,依此类推。

    通过正确的实现,您可以获得 O(n) 时间复杂度和 O(k) 空间复杂度,因为您只需要跟踪大小为 k 的窗口。像这样的:

    // return a winning first move or -1 if there is none
    public int solve(String[] strings, int k) {
        Queue<Boolean> q = new Deque<>();
        int[] lossCount = new int[10];
        for (int i = strings.length - 1; i >= 0; i--) {
            int start = strings[i].charAt(0) - '0';
            int end = strings[i].charAt(strings[i].length() - 1) - '0';
            if (i + k + 1 < strings.length && !q.remove())
                lossCount[strings[i + k + 1].charAt(0) - '0']--;
            boolean win = lossCount[end] == 0;
            if (!win)
                lossCount[start]++;
            else if (i < k)
                return i;
            q.add(win);
        }
        return -1;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-13
      • 2021-08-04
      • 2012-05-20
      • 2015-11-02
      • 1970-01-01
      • 1970-01-01
      • 2013-03-08
      • 2019-04-09
      相关资源
      最近更新 更多