算法题:猜数字游戏
A:猜对且位置对的数字个数。 B:猜对但位置错的数字个数。
"1807"
,如果你猜 "7810"
:1A:数字 8 是对的,且位置正确。 3B:数字 1、0 和 7 是对的,但位置错了。
统计A:找出完全匹配的数字和位置。 统计B:找出数字匹配但位置不对的部分,注意这里不能重复统计。
def get_hint(secret: str, guess: str) -> str:
bulls = 0 # A: 数字和位置都对
cows = 0 # B: 数字对但位置不对
# 用两个数组来统计每个数字出现的频率
secret_count = [0] * 10 # 记录 secret 中未匹配的数字
guess_count = [0] * 10 # 记录 guess 中未匹配的数字
# 第一步:统计完全匹配的部分(A)
for s, g in zip(secret, guess):
if s == g:
bulls += 1 # 完美匹配,直接 +1
else:
# 如果不匹配,把数字频率记录下来
secret_count[int(s)] += 1
guess_count[int(g)] += 1
# 第二步:统计数字匹配但位置不对的部分(B)
for i in range(10):
# 每个数字取它们在 secret 和 guess 中出现次数的最小值
cows += min(secret_count[i], guess_count[i])
# 返回结果
return f"{bulls}A{cows}B"
# 测试一下
print(get_hint("1807", "7810")) # 输出:1A3B
print(get_hint("1123", "0111")) # 输出:1A1B
分步统计:完全匹配(A)和位置错误的匹配(B)必须分开统计,避免重复计数。 频率计数法:用两个数组 secret_count
和guess_count
来记录未匹配数字的频率。每个位置只需要统计0-9这10个数字的频率,空间复杂度是O(10)
,非常小。边界处理:比如全对、全错的情况,代码里都处理得很自然,没有多余的分支判断。
重复统计:一开始粗暴地用字典来统计频率,结果发现有些数字被重复统计了好几次,直接输出错答案。 忘记考虑0:这题的数字是字符串格式,比如 0123
,如果直接转成int
比对,会丢掉前导零,这坑踩得我头疼。
class GuessGame:
def __init__(self, secret: str):
self.secret = secret
def guess(self, guess: str) -> str:
return get_hint(self.secret, guess)
# 初始化游戏
game = GuessGame("1807")
# 玩家开始猜
print(game.guess("7810")) # 输出:1A3B
print("🎯 玩家猜测:7810")
print(f"🧩 提示:{game.guess('7810')}")
对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》。