题目描述
思路解析动画文字版
记住「先逐位抓公牛,再对剩余数字计数取 min 抓奶牛」,下面每帧都在套它。
比第 0 位:secret 是 1、guess 是 7。数字和位置都一样才算公牛。
不相等,第 0 位不是公牛。它的数字留到第二步按计数找奶牛。
比第 1 位:secret 是 8、guess 是 8。数字和位置都一样才算公牛。
相等!第 1 位是公牛(绿色),公牛数加到 1。这位被「用掉」,不再参与奶牛统计。
比第 2 位:secret 是 0、guess 是 1。数字和位置都一样才算公牛。
不相等,第 2 位不是公牛。它的数字留到第二步按计数找奶牛。
比第 3 位:secret 是 7、guess 是 0。数字和位置都一样才算公牛。
不相等,第 3 位不是公牛。它的数字留到第二步按计数找奶牛。
比第 4 位:secret 是 3、guess 是 3。数字和位置都一样才算公牛。
相等!第 4 位是公牛(绿色),公牛数加到 2。这位被「用掉」,不再参与奶牛统计。
比第 5 位:secret 是 4、guess 是 3。数字和位置都一样才算公牛。
不相等,第 5 位不是公牛。它的数字留到第二步按计数找奶牛。
比第 6 位:secret 是 5、guess 是 5。数字和位置都一样才算公牛。
相等!第 6 位是公牛(绿色),公牛数加到 3。这位被「用掉」,不再参与奶牛统计。
逐位扫完,公牛共 3 个(绿)。剩下 4 个没配上的位置(蓝),按「数字」计数来数奶牛——不看位置,只看数字两边各剩几个。
数字 0:非公牛位置里 secret 还剩 1 个、guess 还剩 1 个,能错位配上的是较小值 min(1, 1) = 1,奶牛累计到 1。
数字 1:非公牛位置里 secret 还剩 1 个、guess 还剩 1 个,能错位配上的是较小值 min(1, 1) = 1,奶牛累计到 2。
数字 3:非公牛位置里 secret 还剩 0 个、guess 还剩 1 个,能错位配上的是较小值 min(0, 1) = 0,奶牛累计到 2。
数字 4:非公牛位置里 secret 还剩 1 个、guess 还剩 0 个,能错位配上的是较小值 min(1, 0) = 0,奶牛累计到 2。
数字 7:非公牛位置里 secret 还剩 1 个、guess 还剩 1 个,能错位配上的是较小值 min(1, 1) = 1,奶牛累计到 3。
汇总:公牛 3 个、奶牛 3 个,提示串就是 “3A3B”。公牛只看「位置+数字全对」,奶牛对剩余数字两边取 min。
边界先想清:全对、全不沾、全错位。
面试常问「一遍法」与「推广到任意字符」。
参考代码
class Solution: def getHint(self, secret: str, guess: str) -> str: bulls = 0 cs = [0] * 10 cg = [0] * 10 for a, b in zip(secret, guess): if a == b: bulls += 1 else: cs[ord(a) - 48] += 1 cg[ord(b) - 48] += 1 cows = sum(min(a, b) for a, b in zip(cs, cg)) return f"{bulls}A{cows}B"复杂度
- 时间:O(n),一遍比对 + 10 个数字汇总
- 空间:O(1),两个长度 10 的计数数组
易错点
面试追问把动画讲成自己的话
追问能不能一遍遍历同时数公牛和奶牛?
追问如果不是数字而是任意字符怎么办?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
四数相加 II
LeetCode 454 · 中等 · 沿着 哈希套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题