LeetCode —— 299. 猜数字游戏

LeetCode —— 299. 猜数字游戏

一、题目描述:

你在和朋友一起玩 猜数字(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 仅由数字组成

来源:力扣(LeetCode)

链接:https://leetcode.cn/problems/bulls-and-cows

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

  1. 这道题考察了什么思想?你的思路是什么?

    这道题目我的思路很简单,分别计算A和B的数目。

    计算A的数目通过比较guess和secret两个字符串中位置和字符相等的个数得到。

    如果字符串的某个数字及其位置相等,我们就将A加一。否则我们就把两个字符串这个位置的两个字符放入两个切片中,这两个切片是s和g。

    然后再遍历两个切片,将两个切片中所有数字的数目较小值加到B之上。

    最后使用fmt.Sprintf将A、B格式化到字符串中。

  2. 做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?

    不是一次通过的,出现了下面这个问题:

        for i,v := range guess{
            if v == secret[i]{
                A++
            }else {
                s[secret[i]-'0']++
                g[v-'0']++
            }
        }
    
    Line 5: Char 14: invalid operation: v == secret[i] (mismatched types rune and byte) (solution.go)
    

    就是guess[i]和v的类型不一致,一个是byte,一个是rune。

    for…range遍历字符串每个元素的类型是rune(int32),即utf-8字符对应的unicode码点。用下标来访问的话,每个元素的类型是个byte(uint8)。

  3. 有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?

    func getHint(secret string, guess string) string {
        numA := 0
        numB := 0
        
        arr := [10]int{}
    
        for i:=0;i<len(secret);i++{
            if secret[i]==guess[i] {
                numA++
            } else {
                // 如果secret[i]-'0' 小于0,说明guess中出现了
                // 如果不小于,有两种情况 1、secret中出现的比guess中多 2、guess中没有出现过
    
                // 只要有另一方出现了这个数字,且次数比自己多,那么就有奶牛一只(说白了就是比较两方这个数字出现的次数)
                if (arr[secret[i]-'0'] < 0) {
                    arr[secret[i]-'0']++
                    numB++
                } else {
                    arr[secret[i]-'0']++
                }
                // 同理
                if (arr[guess[i]-'0'] > 0) {
                    arr[guess[i]-'0']--
                    numB++
                } else {
                    arr[guess[i]-'0']--
                }
                
            }
        }
    
        return strconv.Itoa(numA)+"A"+strconv.Itoa(numB)+"B"
    }
    
    作者:dong-180
    链接:https://leetcode.cn/problems/bulls-and-cows/solution/yi-ge-shu-zu-yi-ci-xun-huan-shuang-bai-j-khue/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

三、AC 代码:

func getHint(secret string, guess string) string {
    A,B := 0,0
    s,g := make([]int,10), make([]int,10)
    for i := range guess{
        if guess[i] == secret[i]{
            A++
        }else {
            s[secret[i]-'0']++
            g[guess[i]-'0']++
        }
    }

    for i := range s{
        B += min(g[i],s[i])
    }
    res := fmt.Sprintf("%dA%dB",A,B)
    return res
}

func min(a,b int) int {
    if a>b{
        return b
    }else{
        return a
    }
}

你可能感兴趣的:(leetcode,游戏,算法)