Leetcode299 Bulls and Cows

Leetcode299 Bulls and Cows

题目

You are playing the following Bulls and Cows game with your friend: You write down a number and ask your friend to guess what the number is. Each time your friend makes a guess, you provide a hint that indicates how many digits in said guess match your secret number exactly in both digit and position (called “bulls”) and how many digits match the secret number but locate in the wrong position (called “cows”). Your friend will use successive guesses and hints to eventually derive the secret number.

Write a function to return a hint according to the secret number and friend’s guess, use A to indicate the bulls and B to indicate the cows.

Please note that both secret number and friend’s guess may contain duplicate digits.

Example 1:
Input: secret = “1807”, guess = “7810”
Output: “1A3B”
Explanation: 1 bull and 3 cows. The bull is 8, the cows are 0, 1 and 7.

Example 2:
Input: secret = “1123”, guess = “0111”
Output: “1A1B”
Explanation: The 1st 1 in friend’s guess is a bull, the 2nd or 3rd 1 is a cow.

思路

题中只使用数字,考虑用长度为10的数组先记录每个数字出现的次数,再次遍历。

  1. g u e s s guess guess s e c r e t secret secret第i位相同则A的数量增加
  2. 不相同但 g u e s s guess guess中的数字在 s e c r e t secret secret中出现,B增加

看过第i位后减少数组记录的数量。

这样的话有一个问题, g u e s s guess guess会贪心的匹配 s e c r e t secret secret中处在i位后的相同数字,可能会导致 g u e s s [ i ] = s e c r e t [ i ] guess[i] = secret[i] guess[i]=secret[i]时,数组中记录的个数 r e s t [ i ] < = 0 rest[i] <= 0 rest[i]<=0。修改在判断相等后再次判断 r e s t [ i ] = = 0 rest[i] == 0 rest[i]==0,若成立则B减1。

举例
s e c r e t = " 0122 " , g u e s s = " 2122 " secret = "0122", guess = "2122" secret="0122",guess="2122"
g u e s s [ 0 ] guess[0] guess[0]会匹配 s e c r e t [ 2 ] secret[2] secret[2] g u e s s [ 2 ] guess[2] guess[2]会匹配 s e c r e t [ 3 ] secret[3] secret[3],到 i = 3 i = 3 i=3时,此时 A = 2 A = 2 A=2 B = 1 B = 1 B=1,比较后有 g u e s s [ i ] = s e c r e t [ i ] guess[i] = secret[i] guess[i]=secret[i],但因为 r e s t [ 2 ] = = 0 rest[2] == 0 rest[2]==0,得到 A = 3 A = 3 A=3 B = 0 B = 0 B=0

代码

public String getHint(String secret, String guess) {
        int A = 0, B = 0;
        int[] rest = new int[10];
        for (int i = 0; i < secret.length(); i++) {
            rest[secret.charAt(i) - '0']++;
        }
        for (int i = 0; i < secret.length(); i++) {
            //System.out.println(rest[guess.charAt(i) - '0']);
            if (secret.charAt(i) == guess.charAt(i)) {
                A++;
                if (rest[guess.charAt(i) - '0'] == 0) {
                    B--; // 前面不对位置的多match了一个
                } else {
                    rest[guess.charAt(i) - '0']--;
                }
            } else {
                if (rest[guess.charAt(i) - '0'] != 0) {
                    B++;
                    rest[guess.charAt(i) - '0']--;
                }
            }
        }
        return String.format("%dA%dB", A, B);
    }

优化

看了一下最快的代码,可以只遍历一遍,用两个数组记录出现频率, c o w cow cow的数量就是在每次遍历的时候比较是否有 g u e s s [ i ] guess[i] guess[i]存在于 s e c r e t secret secret的数组中(与之前位数匹配), s e c r e t [ i ] secret[i] secret[i]存在于 g u e s s guess guess的数组中(与之后位数匹配)。

同时 S t r i n g . f o r m a t ( ) String.format() String.format() S t r i n g B u i l d e r StringBuilder StringBuilder多花很多的时间和空间!

修改代码如下

public String getHint(String secret, String guess) {
        int[] secretMap = new int[10];
        int[] guessMap = new int[10];
        int bull = 0;
        int cow = 0;

        for(int i = 0; i < secret.length(); i++) {
            if(secret.charAt(i) == guess.charAt(i)) {
                bull++;
            } else {
                int sDigit = secret.charAt(i) - '0';
                int gDigit = guess.charAt(i) - '0';
                if(guessMap[sDigit] > 0) {
                    guessMap[sDigit]--;
                    cow++;
                } else {
                    secretMap[sDigit]++;
                }
                if(secretMap[gDigit] > 0) {
                    secretMap[gDigit]--;
                    cow++;
                } else {
                    guessMap[gDigit]++;
                }
            }
        }

        StringBuilder sb = new StringBuilder();
        sb.append(bull).append("A").append(cow).append("B");
        return sb.toString();
   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值