最后一天,我一直在努力应对LeetCode 'Bulls & Cows'挑战。我是学习算法过程中的前端开发人员,我很难理解用Java实现的逻辑块并将其移植到我的JavaScript解决方案中。
public String getHint(String secret, String guess) {
int bulls = 0;
int cows = 0;
int[] numbers = new int[10];
for (int i = 0; i<secret.length(); i++) {
int s = Character.getNumericValue(secret.charAt(i));
int g = Character.getNumericValue(guess.charAt(i));
if (s == g) bulls++;
else {
if (numbers[s] < 0) cows++;
if (numbers[g] > 0) cows++;
numbers[s] ++;
numbers[g] --;
}
}
return bulls + "A" + cows + "B";
}
具体来说,我很难理解以下功能块:
else {
if (numbers[s] < 0) cows++;
if (numbers[g] > 0) cows++;
numbers[s] ++;
numbers[g] --;
}
这是我推导出的JS解决方案,它传递了除secret = 1807
和guess = 7810
之外的所有(已知)测试用例:
var getHint = function(secret, guess) {
var bulls = 0;
var cows = 0;
var nums = [];
var checkNums = function(num) {
if(nums.length) {
for (var l = 0; l < nums.length; l++) {
if(num === nums[l]) {
return false;
} else {
nums.push(num);
cows++;
return true;
}
} else {
// /nums/ is equal to 0
cows++;
nums.push(num);
}
}
};
if(guess) {
// iterate over the secret to compare it to the guess
for (var i = 0; i < secret.length; i++) {
// compare the related location to check for bulls
if(secret[i] === guess[i]) {
bulls++;
nums.push(guess[i]);
} else {
// We didnt find a bull, lets check the /guess/ for cows
for(var j = 0; j < guess.length; j++) {
// We have a match, what should we do with it?
if (secret[i] === guess[j]) {
checkNums(guess[j]);
}
}
}
}
}
return bulls + "A" + cows + "B";
};
我得到的失败测试案例是:
Input:
"1807"
"7810"
Output:
"1A2B"
Expected:
"1A3B"
我希望更好地了解如何更好地复制优雅的Java解决方案,以及我可以使这个JS解决方案更简洁(和工作)的任何方法。我越是反对这一点,我写的越多for
循环和if
块,我只知道我向错误的方向移动。
这是我的解决方案的JSBin:
http://jsbin.com/jibusa/edit?js,console
感谢您的帮助。
答案 0 :(得分:1)
以下是Java解决方案的虚拟副本。对JavaScript charCodeAt()
的一点调整是为了解释它与Java Character.getNumericValue
的差异。
function getHint(secret, guess) {
var bulls = 0;
var cows = 0;
var numbers = new Array(10);
for (var i=0; i<10; i++){
numbers[i] = 0;
}
for (var i = 0; i<secret.length; i++) {
var s = secret.charCodeAt(i) - 48;
var g = guess.charCodeAt(i) - 48;
if (s == g) bulls++;
else {
if (numbers[s] < 0) cows++;
if (numbers[g] > 0) cows++;
numbers[s] ++;
numbers[g] --;
}
}
return bulls + "A" + cows + "B";
}
console.log(getHint("1807","7810"));
答案 1 :(得分:1)
numbers[x]
表示秘密前缀中的不匹配x
的数量以及到目前为止扫描的猜测。正数表明秘密有盈余。负数表示猜测过剩。
代码块
if (numbers[s] < 0) cows++;
if (numbers[g] > 0) cows++;
numbers[s] ++;
numbers[g] --;
如下翻译为英语。如果s
,秘密中的当前字母在猜测中有剩余,则它与猜测中的前一个字母匹配,因此增加奶牛的数量。如果g
,猜测中的当前字母在秘密中有剩余,那么它与秘密中的前一个字母匹配,因此增加奶牛的数量。 numbers[s] ++
非常光滑:要么在猜测中删除剩余字母,要么在秘密中创造盈余。同样地,numbers[g] --
要么删除秘密中的剩余字母,要么在猜测中创建一个字母。
答案 2 :(得分:0)
你为什么不这样做?...
var getHint = function(secret, guess) {
var bulls = 0;
var cows = 0;
var nums = [];
var length = 10;
var s;
var g;
for (var i2=0; i2 < length; i2++) {nums[i2] = 0;}
for (var i=0; i < secret.length; i++) {
s = Number(String(secret).charAt(i));
g = Number(String(guess).charAt(i));
if(s == g)bulls++;
else{
if(nums[s] < 0)cows++;
if(nums[g] > 0) cows++;
nums[s]++;
nums[g]--;
}
}
return bulls + "A" + cows + "B";
};
console.log(getHint("1123", "0111"));
console.log(getHint("1807", "7810"));
输出继电器:
"1A1B"
"1A3B"