题目及解题思路来源6.3算法小节:【前端工程师面试宝典】学习说明_互联网校招面试真题面经汇总_牛客网
题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2-10为数字本身,A为1,J为11,Q为12,K为13,而大小王可以看成任意数字。
思路:
1)确认5张牌中除了0,其余数字没有重复的(可以用表统计的方法);
2) 满足这样的逻辑:(max,min分别代表5张牌中的除0以外的最大值最小值)
如果没有0,则max-min=4,则为顺子,否则不是
如果有一个0,则max-min=4或者3,则为顺子,否则不是
如果有两个0,则max-min=4或者3或者2,则为顺子,否则不是。最大值和最小值在1)中就可以获得,这样就 不用排序了
实现:
//判断数组是否有除0外的重复元素
function exceptZero(arr) {
var z = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] === 0) {
z++;
}
}
let arr2 = [...new Set(arr)];
if (arr2.length == arr.length + 1 - z) {
return true;
}
}
//将A,J,Q,K,大王,小王变为1,11,12,13,0,0
function change(arr) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] == 'A') { arr[i] = 1; }
if (arr[i] == 'J') { arr[i] = 11; }
if (arr[i] == 'Q') { arr[i] = 12; }
if (arr[i] == 'K') { arr[i] = 13; }
if (arr[i] == '大王') { arr[i] = 0; }
if (arr[i] == '小王') { arr[i] = 0; }
}
}
//数组中0元素的个数
function Zero(num) {
return num == 0;
}
//判断同花顺
function tonghuaS(arr) {
var len = arr.length;
if (len != 5) {
return console.log('请抽五张牌!');
}
change(arr);
//sort()使用时按最高位排序,可能会不准确,用一个函数来修正它
arr.sort(function (a, b) { return a - b });
if (!exceptZero(arr)) {
return console.log('不是同花顺');
}
var len0 = arr.filter(Zero).length;
console.log(len0);
if (len0 === 0 && arr[len - 1] - arr[len0] === 4) {
return console.log('是同花顺');
} else if (len0 === 1 && arr[len - 1] - arr[len0] === 3 || arr[len - 1] - arr[len0] === 4) {
return console.log('是同花顺');
} else if (len0 === 2 && arr[len - 1] - arr[len0] === 2 || arr[len - 1] - arr[len0] === 3 || arr[len - 1] - arr[len0] === 4) {
return console.log('是同花顺');
} else {
return console.log('不是同花顺');
}
}
//判断
var c = ['K', 10, 'Q', 9, '大王'];
tonghuaS(c);
总结:
(1)对于数组的排序,直接使用sort()可能会不准确,调用时可以使用arr.sort(function(a,b){return a-b;});来修正,原理:a代表前一个数,b代表后一个数,a-b>0时,前面的数大,两数交换位置,a-b<0时不交换。同理,若return b-a;则为倒序排列。
(2)虽然提示思路中说不用排序,但我觉得排序之后我自己看会更清晰一点(还是菜)
(3)0的个数作为判断条件那里,可以不必直接计算0的个数,而可以用indexOf(0)==lastIndexOf(0),!=和==-1来表示2个,1个和0个0,没有敲,但应该可以。