leetcode题解-299. 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.
示例:
Secret number: “1807”
Friend’s guess: “7810”
Hint: 1 bull and 3 cows. (The bull is 8, the cows are 0, 1 and 7.)
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. In the above example, your function should return “1A3B”.
Please note that both secret number and friend’s guess may contain duplicate digits, for example:
Secret number: “1123”
Friend’s guess: “0111”
In this case, the 1st 1 in friend’s guess is a bull, the 2nd or 3rd 1 is a cow, and your function should return “1A1B”.
You may assume that the secret number and your friend’s guess only contain digits, and their lengths are always equal.

本题其实比较简单,为了获得所谓提示hint,就是获取bull和cow的个数。bull很容易得到,一个for循环,对应位置字符相等则为bull,计数加一即可。而cow则是除去bull之外两个字符串中相同元素的个数(不考虑位置信息)。
一开始写下了如下代码,当时考虑分别记录secret和guess两个数组数字和其出现次数,所以使用了hashmap来存。由于hashMap在这里相对而言比较耗时,性价比不高,所以只击败了14%的用户。代码入下:

    public static String getHint(String secret, String guess) {
        int bull = 0, cow = 0;
        HashMap bulls = new HashMap<>();
        HashMap cows = new HashMap<>();
        for(int i=0; iif(secret.charAt(i) == guess.charAt(i))
                bull += 1;
            else{
                if(bulls.containsKey(secret.charAt(i)))
                    bulls.put(secret.charAt(i), bulls.get(secret.charAt(i))+1);
                else
                    bulls.put(secret.charAt(i), 1);
                if(cows.containsKey(guess.charAt(i)))
                    cows.put(guess.charAt(i), cows.get(guess.charAt(i))+1);
                else
                    cows.put(guess.charAt(i), 1);
            }
        }
        for(Character key : bulls.keySet()){
            if(cows.containsKey(key)){
                if(bulls.get(key) > cows.get(key))
                    cow += cows.get(key);
                else cow += bulls.get(key);
            }
        }
        return bull + "A" + cow + "B";
    }

看到代码执行效率如此低下,想想该怎么改进呢?于是便想到数字信息可以使用数组的索引来表示,这样就省去了hashMap这样复杂的数据结构,使得程序匀速速度得以提升,击败了44%的用户。代码入下:

    public static String getHint1(String secret, String guess) {
        int bull = 0, cow = 0;
        int [] bulls = new int [10];
        int [] cows = new int [10];
        for(int i=0; iif(secret.charAt(i) == guess.charAt(i))
                bull += 1;
            else{
                bulls[secret.charAt(i) - 48] ++;
                cows[guess.charAt(i) - 48] ++;
            }
        }
        for(int i=0; i<10; i++){
            if(bulls[i]!=0){
                if(bulls[i] > cows[i])
                    cow += cows[i];
                else cow += bulls[i];
            }
        }
        return bull + "A" + cow + "B";
    }

所以呢,看看还有没有提升的空间,由于上面的代码都是使用了两个数组来保存secret和guess的信息,然后在程序最后使用一个循环来遍历得到cow个数,这其实忽略了其二者的关系,我们可以只使用一个数组来保村0-9这10个数字出现的次数,secret每出现一次便加一,guess每出现一次便减一。而且当其发生正负关系变化的时候cow才加一。这样效率就有提升了一些。这里有两段代码,前面一段54%,后面一段73%。其实代码思想完全相同,不过在中间使用变量的方式不同。所以这提醒我们提高代码效率时不仅仅可以从算法上考虑还可以从编程习惯和程序规范上下手。

    public String getHint2(String secret, String guess) {
        int bull = 0;
        int cow = 0;
        int[] numbers = new int[10];
        for (int i = 0; iif (secret.charAt(i) == guess.charAt(i)) bull++;
            else {
                if (numbers[secret.charAt(i)-'0']++ < 0) cow++;
                if (numbers[guess.charAt(i)-'0']-- > 0) cow++;
            }
        }
        return bull + "A" + cow + "B";
    }
    public String getHint3(String secret, String guess) {
        int s, g, size = secret.length();
        int bulls = 0, cows = 0;
        int [] nums = new int [10];
        for (int i = 0; i < size; i++) {
            s = secret.charAt(i) - '0';
            g = guess.charAt(i) - '0';
            if (s == g)
                bulls ++;
            else{
                if (nums[s] < 0)
                    cows++;
                nums[s]++;
                if (nums[g] > 0)
                    cows++;
                nums[g]--;
            }
        }
        return bulls + "A" + cows + "B";
    }

你可能感兴趣的:(leetcode刷题)