程序员面试金典 - 面试题 16.15. 珠玑妙算

题目难度: 简单

原题链接

今天继续更新程序员面试金典系列, 大家在公众号 算法精选 里回复 面试金典 就能看到该系列当前连载的所有文章了, 记得关注哦~

题目描述

珠玑妙算游戏(the game of master mind)的玩法如下。

计算机有 4 个槽,每个槽放一个球,颜色可能是红色(R)、黄色(Y)、绿色(G)或蓝色(B)。例如,计算机可能有 RGGB 4 种(槽 1 为红色,槽 2、3 为绿色,槽 4 为蓝色)。作为用户,你试图猜出颜色组合。打个比方,你可能会猜 YRGB。要是猜对某个槽的颜色,则算一次“猜中”;要是只猜对颜色但槽位猜错了,则算一次“伪猜中”。注意,“猜中”不能算入“伪猜中”。

给定一种颜色组合 solution 和一个猜测 guess,编写一个方法,返回猜中和伪猜中的次数 answer,其中 answer[0]为猜中的次数,answer[1]为伪猜中的次数。

示例:

  • 输入: solution=“RGBY”,guess=“GGRR”
  • 输出: [1,1]
  • 解释: 猜中 1 次,伪猜中 1 次。

提示:

  • len(solution) = len(guess) = 4
  • solution 和 guess 仅包含"R",“G”,“B”,"Y"这 4 种字符

题目思考

  1. 如何计算伪猜中次数?

解决方案

思路
  • 分析题目, 我们可以很容易地计算出猜中次数, 即遍历下标, 查看当前位置的字符是否相等, 那如何计算伪猜中次数呢?
  • 我们可以将剩余字符分别存入两个计数字典中, 然后遍历其中任意一个字典的 key, 查看该 key 是否也在另一个字典中
  • 是的话则说明该字符同时出现在两个字符串中, 但位置不同, 属于伪猜中, 两者计数较小值即为当前字符伪猜中次数, 将其累加到最终结果里
  • 下面代码就对应了上面的整个过程, 且每一步有详细的注释, 方便大家理解
复杂度
  • 时间复杂度 O(N): 需要遍历 N 个字符
  • 空间复杂度 O(N): 计数字典存最多 N 个字符
代码
class Solution:
    def masterMind(self, solution: str, guess: str) -> List[int]:
        # 需要两次遍历, 先计算完全正确的, 然后排除它们再计算其他的, 每个字符只能使用一次
        res = [0, 0]
        cs = collections.defaultdict(int)
        cg = collections.defaultdict(int)
        n = len(solution)
        for i in range(n):
            s, g = solution[i], guess[i]
            if s == g:
                # 完全匹配, 猜中次数加1
                res[0] += 1
            else:
                # 非完全匹配, 加入计数字典
                cs[s] += 1
                cg[g] += 1
        for s in cs:
            if s in cg:
                # 相同字符同时出现在两个字符串中, 但位置不同, 属于伪猜中, 两者计数较小值即为当前字符伪猜中次数
                res[1] += min(cs[s], cg[s])
        return res

大家可以在下面这些地方找到我~😊

我的 GitHub

我的 Leetcode

我的 CSDN

我的知乎专栏

我的头条号

我的牛客网博客

我的公众号: 算法精选, 欢迎大家扫码关注~😊

算法精选 - 微信扫一扫关注我

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值