LC 299. 猜数字游戏

题目描述

这是 LeetCode 上的 299. 猜数字游戏 ,难度为 中等

你在和朋友一起玩 猜数字(Bulls and Cows)游戏,该游戏规则如下:

写出一个秘密数字,并请朋友猜这个数字是多少。朋友每猜测一次,你就会给他一个包含下述信息的提示:

  • 猜测数字中有多少位属于数字和确切位置都猜对了(称为 "Bulls", 公牛),
  • 有多少位属于数字猜对了但是位置不对(称为 "Cows", 奶牛)。也就是说,这次猜测中有多少位非公牛数字可以通过重新排列转换成公牛数字。

给你一个秘密数字 secret 和朋友猜测的数字 guess,请你返回对朋友这次猜测的提示。

提示的格式为 "xAyB"x 是公牛个数, y 是奶牛个数,A 表示公牛,B 表示奶牛。

请注意秘密数字和朋友猜测的数字都可能含有重复数字。

示例 1:

1
2
3
4
5
6
7
8
输入: secret = "1807", guess = "7810"

输出: "1A3B"

解释: 数字和位置都对(公牛)用 '|' 连接,数字猜对位置不对(奶牛)的采用斜体加粗标识。
"1807"
|
"7810"

示例 2:
1
2
3
4
5
6
7
8
9
输入: secret = "1123", guess = "0111"

输出: "1A1B"

解释: 数字和位置都对(公牛)用 '|' 连接,数字猜对位置不对(奶牛)的采用斜体加粗标识。
"1123" "1123"
| or |
"0111" "0111"
注意,两个不匹配的 1 中,只有一个会算作奶牛(数字猜对位置不对)。通过重新排列非公牛数字,其中仅有一个 1 可以成为公牛数字。

示例 3:
1
2
3
输入:secret = "1", guess = "0"

输出:"0A0B"

示例 4:
1
2
3
输入:secret = "1", guess = "1"

输出:"1A0B"

提示:

  • 1 <= secret.length, guess.length <= 1000
  • secret.length == guess.length
  • secret 和 guess 仅由数字组成

模拟

根据题意,我们可以对 $secret$ 和 $guess$ 进行诸位比较,统计公牛数量 $a$ 和奶牛数量 $b$。

对于字符相同的位置,我们可以直接对 $a$ 进行自增;对于字符不同的位置,使用「哈希表」进行分别统计 $secret$ 和 $guess$ 的词频,某个数字 $x$ 在两者词频中的较小值,即为该数字对应的奶牛数量,统计所有数字 $[0, 9]$ 的奶牛数量总和即为 $b$。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public String getHint(String secret, String guess) {
int n = secret.length();
int a = 0, b = 0;
int[] cnt1 = new int[10], cnt2 = new int[10];
for (int i = 0; i < n; i++) {
int c1 = secret.charAt(i) - '0', c2= guess.charAt(i) - '0';
if (c1 == c2) {
a++;
} else {
cnt1[c1]++;
cnt2[c2]++;
}
}
for (int i = 0; i < 10; i++) b += Math.min(cnt1[i], cnt2[i]);
return a + "A" + b + "B";
}
}

  • 时间复杂度:$O(n)$
  • 空间复杂度:令 $C$ 为字符集大小,$C$ 固定为 $10$。复杂度为 $O(C)$

最后

这是我们「刷穿 LeetCode」系列文章的第 No.299 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!