☀(day41)
目录
📝题目:
你在和朋友一起玩 猜数字(Bulls and Cows)游戏,该游戏规则如下:
写出一个秘密数字,并请朋友猜这个数字是多少。朋友每猜测一次,你就会给他一个包含下述信息的提示:
猜测数字中有多少位属于数字和确切位置都猜对了(称为 "Bulls",公牛),
有多少位属于数字猜对了但是位置不对(称为 "Cows",奶牛)。也就是说,这次猜测中有多少位非公牛数字可以通过重新排列转换成公牛数字。
给你一个秘密数字 secret 和朋友猜测的数字 guess ,请你返回对朋友这次猜测的提示。
提示的格式为 "xAyB" ,x 是公牛个数, y 是奶牛个数,A 表示公牛,B 表示奶牛。
请注意秘密数字和朋友猜测的数字都可能含有重复数字。
- 1 <= secret.length, guess.length <= 1000
- secret.length == guess.length
- secret 和 guess 仅由数字组成
⭐示例 1:
输入:secret = "1807", guess = "7810"
输出:"1A3B"
解释说明:数字和位置都对(公牛)用 '|' 连接,数字猜对位置不对(奶牛)的采用斜体加粗标识。
"1807"
|
"7810"
⭐示例 2:
输入:secret = "1123", guess = "0111"
输出:"1A1B"
解释说明:数字和位置都对(公牛)用 '|' 连接,数字猜对位置不对(奶牛)的采用斜体加粗标识。
"1123" "1123"
| or |
"0111" "0111"
注意,两个不匹配的 1 中,只有一个会算作奶牛(数字猜对位置不对)。通过重新排列非公牛数字,其中仅有一个 1 可以成为公牛数字。
🚩题目分析:
刚看题目我也是有些蒙,不懂题目在说什么,后来静下来看题目发现题目也蛮简单的。
题目给出secret和guess一个是你写出的数字一个是朋友猜的数字。我们要做的就是比较这两个数字中:
1.在同一位置上的数是否相同,并给出有几个相同。
2.除去符合条件一的数,guess剩下的数是否可以经过重新排列使得满足条件1,并给出有几个数可以排列后满足。
如例2中secret = "1123", guess = "0111"
两个1对应位置和数字都相同,所以为“公牛”(A),剩下的对应位置的数都不同,那么我们将guess重新排列=== > guess = "1110"或"1101"或....,这时我们可以将后两个不同1移到第一位这样就与secret的第一个数相同,但是guess中后两个不同位置的1我们把它看成是一样的,那么意味着“母牛”(B)只有一个。
所以你需要给朋友提示1A1B
💡解题思路:
由分析我们可以同时遍历两个字符串(secret和guess,两个字符串一样长),并判断同一位置上的数是否相同,
相同我们则将“公牛”计数+1。
如果不同我们则记录该数在secret和guess中各自出现的数目,并用字典储存。
储存方式为,{‘某数字’:出现的次数}
最后判断用于储存secret数目出现次数的字典中的元素是否在用于储存guess数目出现次数的字典中,如果在则取该数字在两个字符串中出现次数最小那个即可。
如例2中,
除去再同一位置相同的数字(标黄色的数),secret和guess中只同时含有1
secret中1出现的次数为1次
guess中1出现次数为2次
这时我们取1即可满足“母牛的要求”
🌟解法一:
🌈代码实现
def getHint(secret, guess):
bulls, cows = 0, 0
dic_s = dict()
dic_g = dict()
for i, c in enumerate(secret):
if guess[i] == c:
bulls += 1
else:
dic_s[c] = dic_s.get(c, 0) + 1
dic_g[guess[i]] = dic_g.get(guess[i], 0) + 1
for i in dic_s:
if i in dic_g:
cows += min(dic_g[i], dic_s[i])
return str(bulls) + 'A' + str(cows) + 'B'
✏代码注释
def getHint(secret, guess):
bulls, cows = 0, 0 # 初始化计数变量
dic_s = dict() # 初始化用于储存数字出现次数的字典
dic_g = dict()
for i, c in enumerate(secret): # 使用enumerate()函数获取secret中元素的索引i和元素c
if guess[i] == c: # 判断guess和secret同一位置的数是否相等
bulls += 1 # 相等则公牛计数+1
else: # 如果不相等
dic_s[c] = dic_s.get(c, 0) + 1 # 实用字典储存该位置上的数出现的次数
dic_g[guess[i]] = dic_g.get(guess[i], 0) + 1
for i in dic_s: # 接着遍历字典dic_s,并判断dic_s中的元素是否在dic_g中
if i in dic_g:
cows += min(dic_g[i], dic_s[i]) # 实用min取小
return str(bulls) + 'A' + str(cows) + 'B'
这里的
dic_s[c] = dic_s.get(c, 0) + 1相当于
dic_s[c] = 0
dic_s[c] = [i] + 1
----------------------------------------------
如
srt = '1223'
for i in srt:
dic_s.get(i, 0) + 1
print(dic_s)
输出:
{'1':1, '2': 2, '3': 1}
🌟解法一:
思路和基本一样,不过我们这次使用sum()函数直接统计公牛和母牛的数量,使用Counter()函数统计secret和guess中每个数出现的次数并用字典储存。
Counter()的作用相当于上面的dic_s[c] = dic_s.get(c, 0) + 1
🌈代码实现
from collections import Counter
def getHint(secret, guess):
bull = sum(secret[i] == guess[i] for i in range(len(secret)))
cow = sum((Counter(secret) & Counter(guess)).values()) - bull
return f'{bull}A{cow}B'
这里cow用sum求总量后需要减去对应位置相同数字的次数,也就是减去公牛(bull)的数目才是母牛(cow)正真的数目
今天就到这,明天见。🚀
❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄end❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄