LeetCode题练习与总结:猜数字游戏--299

310 篇文章 0 订阅
184 篇文章 0 订阅

一、题目描述

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

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

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

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

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

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

示例 1:

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

示例 2:

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

提示:

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

二、解题思路

  1. 遍历 secret 和 guess 字符串,比较每一位字符是否相同。如果相同,则公牛(Bulls)数量加一。
  2. 使用一个长度为 10 的数组(记为 cnt)来记录 secret 中每一位数字出现的次数(0-9),以及 guess 中每一位数字出现的次数。
  3. 再次遍历 secret 和 guess 字符串,如果字符不同,则分别将它们在 cnt 数组中的对应位置加一。
  4. 遍历 cnt 数组,对于每一位数字,取其在 secret 和 guess 中出现次数的较小值,累加到奶牛(Cows)数量上。
  5. 根据公牛和奶牛的数量,构造并返回结果字符串。

三、具体代码

class Solution {
    public String getHint(String secret, String guess) {
        int bulls = 0;  // 公牛数量
        int cows = 0;   // 奶牛数量
        int[] cntS = new int[10];  // secret 中数字出现的次数
        int[] cntG = new int[10];  // guess 中数字出现的次数
        
        for (int i = 0; i < secret.length(); i++) {
            char s = secret.charAt(i);
            char g = guess.charAt(i);
            
            if (s == g) {
                bulls++;  // 数字和位置都猜对了,公牛数量加一
            } else {
                cntS[s - '0']++;  // secret 中对应数字出现次数加一
                cntG[g - '0']++;  // guess 中对应数字出现次数加一
            }
        }
        
        for (int i = 0; i < 10; i++) {
            cows += Math.min(cntS[i], cntG[i]);  // 取 secret 和 guess 中对应数字出现次数的较小值,累加到奶牛数量上
        }
        
        return bulls + "A" + cows + "B";  // 构造并返回结果字符串
    }
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 第一个 for 循环遍历了字符串 secret 和 guess 一次,其长度为 n(假设两个字符串长度相等),因此这个循环的时间复杂度为 O(n)。

  • 第二个 for 循环遍历了一个长度为 10 的固定数组,因此这个循环的时间复杂度为 O(1),因为循环次数是常数。

由于两个循环是顺序执行的,总的时间复杂度就是两个循环时间复杂度的和,即 O(n) + O(1) = O(n)。

2. 空间复杂度
  • bulls 和 cows 是两个整型变量,它们占用的空间是常数,即 O(1)。

  • cntS 和 cntG 是两个长度为 10 的整型数组,它们占用的空间也是常数,即 O(1)。

由于我们只使用了固定大小的额外空间,不随输入字符串长度的增加而增加,因此总的空间复杂度为 O(1)。

五、总结知识点

  1. 类定义class Solution 定义了一个名为 Solution 的类。

  2. 方法定义public String getHint(String secret, String guess) 定义了一个公共方法 getHint,它接受两个字符串参数并返回一个字符串。

  3. 基本数据类型int 用于定义整数变量 bulls 和 cows,用于存储公牛和奶牛的数量。

  4. 数组int[] cntS 和 int[] cntG 定义了两个整型数组,用于记录 secret 和 guess 中每个数字出现的次数。

  5. 循环结构for 循环用于遍历字符串和数组。第一个 for 循环用于遍历字符串 secret 和 guess,第二个 for 循环用于遍历长度为 10 的数组。

  6. 字符操作:使用 charAt(int index) 方法从字符串中获取指定位置的字符。

  7. 字符与整数的转换:通过 '0' 将字符转换为对应的整数(例如,'0' -> 0, '1' -> 1, …)。

  8. 条件语句if 语句用于检查两个字符是否相等,从而确定是否为公牛。

  9. 数组操作:数组元素通过索引访问,并进行递增操作以记录数字出现的次数。

  10. 数学函数Math.min(int a, int b) 用于计算两个整数中的最小值。

  11. 字符串拼接:使用 + 运算符将整数转换为字符串,并与其他字符串拼接构造最终的返回结果。

  12. 方法返回值:使用 return 语句返回方法的结果。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直学习永不止步

谢谢您的鼓励,我会再接再厉的!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值