好的,我们来详细讲解一下 LeetCode 299 题 “Bulls and Cows”。
题目描述
你正在和你的朋友玩一个名为 “Bulls and Cows” 的游戏。你写下一个秘密数字,让你的朋友猜这个数字。每次你的朋友猜一个数字,你给出两个反馈:
- “Bulls”:猜对的数字个数且位置正确。
- “Cows”:猜对的数字个数但位置不正确。
你需要根据你的朋友的猜测和秘密数字,给出相应的 “Bulls” 和 “Cows” 的数量。
示例 1:
输入: secret = "1807", guess = "7810"
输出: "1A3B"
解释: 1 Bulls 和 3 Cows。Bulls 是 '8',Cows 是 '1', '0' 和 '7'。
示例 2:
输入: secret = "1123", guess = "0111"
输出: "1A1B"
解释: 1 Bulls 和 1 Cows。Bulls 是 '1',Cows 是 '1'。
解题思路
我们可以通过以下步骤来解决这个问题:
-
初始化计数器:
bulls
:记录 “Bulls” 的数量。cows
:记录 “Cows” 的数量。secret_count
:一个长度为 10 的数组,用于记录秘密数字中每个数字出现的次数。guess_count
:一个长度为 10 的数组,用于记录猜测数字中每个数字出现的次数。
-
遍历秘密数字和猜测数字:
- 对于每一对相应的数字,如果它们相等,则增加
bulls
的数量。 - 无论是否相等,都更新
secret_count
和guess_count
数组,记录每个数字出现的次数。
- 对于每一对相应的数字,如果它们相等,则增加
-
计算 “Cows” 的数量:
- 对于每个数字 0-9,”Cows” 的数量是该数字在
secret_count
和guess_count
中出现次数的最小值之和。
- 对于每个数字 0-9,”Cows” 的数量是该数字在
-
格式化输出结果:
- 将
bulls
和cows
的数量格式化为 “xAyB” 的形式。
- 将
代码实现
以下是 Python 的实现代码:
class Solution:
def getHint(self, secret, guess):
bulls = 0
cows = 0
secret_count = [0] 10
guess_count = [0] 10
# 遍历秘密数字和猜测数字
for s, g in zip(secret, guess):
if s == g:
bulls += 1
secret_count[int(s)] += 1
guess_count[int(g)] += 1
# 计算 Cows 的数量
for i in range(10):
cows += min(secret_count[i], guess_count[i])
# Cows 需要减去 Bulls 的数量,因为 Bulls 也被计算在内
cows -= bulls
return f"{bulls}A{cows}B"
示例用法
sol = Solution() print(sol.getHint("1807", "7810")) # 输出: "1A3B" print(sol.getHint("1123", "0111")) # 输出: "1A1B"
详细解释
-
初始化:
bulls
和cows
初始化为 0。secret_count
和guess_count
是长度为 10 的数组,用于记录每个数字(0-9)出现的次数。
-
遍历和计数:
- 使用
zip(secret, guess)
来同时遍历secret
和guess
。 - 如果
s == g
,则说明这个位置上的数字是 “Bulls”,增加bulls
的计数。 - 无论是否相等,都更新
secret_count
和guess_count
,记录每个数字出现的次数。
- 使用
-
计算 “Cows”:
- 对于每个数字 0-9,”Cows” 的数量是该数字在
secret_count
和guess_count
中出现次数的最小值之和。 - 由于 “Bulls” 也被计算在内,所以需要从总 “Cows” 中减去 “Bulls” 的数量。
- 对于每个数字 0-9,”Cows” 的数量是该数字在
-
格式化输出:
- 使用格式化字符串
f"{bulls}A{cows}B"
来生成最终的结果。
- 使用格式化字符串
希望这个详细的解释和代码实现能帮助你理解并解决 LeetCode 299 题 “Bulls and Cows”。如果有任何进一步的问题,欢迎继续提问!
发表回复