如何修正getNumOfCows方法以正确统计Bulls and Cows中的奶牛数
修正奶牛数统计方法的问题
你的getNumOfCows方法目前存在两个核心问题:
- 没有排除公牛位置的数字:当前的双重循环会把相同位置的匹配数字(也就是公牛)也计入奶牛数,这就导致
getNumOfCows(secret, guessTwo)返回3而不是0; - 重复计数问题:如果数组中有重复数字,比如
secret = {2,2}、guess = {2,1},你的代码会把secret里的两个2都和guess里的2匹配,返回2,但实际奶牛数应该是1。
正确的思路
要准确统计奶牛数,我们需要:
- 先排除所有公牛位置的数字(这些已经被
getNumOfBulls统计过,不能重复计算); - 统计剩余数字中,两个数组共同拥有的数字数量(注意要考虑重复数字的出现次数,比如secret有2个3,guess有3个3,非公牛位置的话最多算2个匹配)。
修正后的代码
我们可以通过统计数字频率的方式来实现,代码如下:
// 获取猜测中的奶牛数的方法 --- 已修正 public static int getNumOfCows(int[] secretNumber, int[] guessedNumber) { // 先检查数组长度是否一致 if (guessedNumber.length != secretNumber.length) { throw new IllegalArgumentException ("Both array must contain the same number of elements"); } // 先复用已有的公牛数统计方法,得到公牛数量 int bullCount = getNumOfBulls(secretNumber, guessedNumber); // 用两个数组统计0-9每个数字在非公牛位置的出现次数 int[] secretDigitCounts = new int[10]; int[] guessDigitCounts = new int[10]; // 遍历数组,只统计非公牛位置的数字 for (int i = 0; i < secretNumber.length; i++) { if (secretNumber[i] != guessedNumber[i]) { secretDigitCounts[secretNumber[i]]++; guessDigitCounts[guessedNumber[i]]++; } } // 计算奶牛数:每个数字取两者中较小的出现次数,累加总和 int numberOfCows = 0; for (int i = 0; i < 10; i++) { numberOfCows += Math.min(secretDigitCounts[i], guessDigitCounts[i]); } return numberOfCows; }
验证你的示例
我们用你给出的测试用例验证:
secret = {2, 0, 6, 9},guessTwo = {2, 0, 6, 2}:公牛数是3,非公牛位置的secret数字是9,guess数字是2,没有匹配,所以奶牛数返回0,符合预期;secret = {2, 0, 6, 9},guessOne = {9, 5, 6, 2}:公牛数是1,非公牛位置的secret数字是2、0、9,guess数字是9、5、2,匹配的数字是2和9,所以奶牛数返回2,符合预期;guessThree = {1, 2, 3, 4, 5, 6},guessFour = {1, 3, 4, 4, 0, 5}:公牛数是2,非公牛位置的secret数字是2、3、5、6,guess数字是3、4、0、5,匹配的数字是3和5,所以奶牛数返回2,符合预期。
内容的提问来源于stack exchange,提问作者Maya
相关产品推荐
相关产品推荐

