京东前端第一批笔试8.27(AK)
题型:选择题20*2=40,编程题3*20=60(编程终于AK一次!!!)
选择题
考点挺丰富的前端、数据结构算法、计网都涵盖了
编程题第一题:大小写
题目大意:有一个包含大小写的字符串,长为n,现在要求把前k位转换为大写,后面的n-k位转换为小写
解题思路:没什么好说的,分割字符串转换大小写后拼接
代码实现:
function fn(s, k) { return s.slice(0,k).toUpperCase() + s.slice(k).toLowerCase(); } // test let s = 'AbcDd'; console.log(fn(s, 3)); // 'ABCdd'
编程题第二题:矩阵相邻和为奇数
题目大意:有一个大小为n*n的矩阵,里面的元素分别是1~n*n,要求相邻元素之间的和为奇数,输出一种符合要求的矩阵即可
示例:
输入:输入n
3
输出:n行,每行包含n个整数
3 2 1 4 5 6 9 8 7
解题思路:与其说这题是算法题,不如说是脑筋急转弯
两个关键:
奇+偶 = 奇,说明奇偶是间隔排布的
按顺序写一下n=3和n=4的矩阵你就会发现问题很简单
n = 3 (代表n为奇数的情况) 1 2 3 4 5 6 7 8 9 这样已经符合要求了 n = 4(代表n为偶数的情况) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 这样不符合要求,但是只需要将奇数行或者偶数行翻转一下就符合要求了 即(我翻转偶数行) 1 2 3 4 8 7 6 5 9 10 11 12 16 15 14 13
代码实现:
function fn(n) { let arr = [...new Array(Math.pow(n,2)+1).keys()].slice(1); let matrix = constMatrix(n, n, arr); if (n % 2 === 0) { for (let i = 0; i < n; i++) { if (i % 2 === 0) { continue; } else { matrix[i] = matrix[i].reverse(); } } return matrix; } else { return matrix; } } function constMatrix(m, n, arr) { let matrix = []; for (let i = 0; i < m; i++) { let temp = arr.slice(i*m, i*m+n); matrix.push([...temp]); } return matrix; } // 最后注意输出格式 let n = 3; let res = fn(n); for (let item of res) { console.log(item.join(' ')); }
编程题第三题:长城soeasy
题目大意:这样的形式为长城数{1,5,1,5,1,5,1},给你一个数组,每次操作都可以把数组一个元素变成另一个元素的大小,求变成长城数最少操作次数
示例:
输入:n个整数1 1 4 5 1 4
输出:最少操作次数
3
解释:
变为长城数{1,5,1,5,1,5},最少次数为3
解题思路:
这题和之前做过的长城数有点像,之前是每次操作+1,问最少操作次数
一个关键:
原数组根据索引分为两个数组,长城数要求两个数组各自的元素相同
所以问题转换为“最小操作次数使数组元素相等”,最简单的思路就是统计数组元素出现次数,那么数组长度减去出现次数最多的元素的次数就是要求的最小操作次数
一个注意点:如果两个数组恰好出现次数最多的元素相等,这样是不符合长城数的条件的,所以要进行判断
代码实现:function fn(n, arr) { let arr1 = [], arr2 = []; for (let i = 0; i < n; i++) { if (i % 2 === 0) { arr1.push(arr[i]); } else { arr2.push(arr[i]); } } let len1 = arr1.length, len2 = arr2.length; let m1 = getCount(arr1), m2 = getCount(arr2); // 判断 if (m1[0][0] !== m2[0][0]) { return len1 - m1[0][1] + len2 - m2[0][1]; } else { // 必须承认的是,这里有点面向结果编程,哈哈哈哈,完全没考虑m1和m2长度为1的情况,按照严谨地来说要分别判断不同的情况 return Math.min(len1 - m1[1][1] + len2 - m2[0][1], len1 - m1[0][1] + len2 - m2[1][1]) /* 严谨修改:(写得有点繁琐) if (m1[0][0] !== m2[0][0]) { return left.length - m1[0][1] + right.length - m2[0][1]; } else { if (!m1[1] && m2[1]) { return left.length - m1[0][1] + right.length - m2[1][1]; } else if (m1[1] && !m2[1]) { return left.length - m1[1][1] + right.length - m2[0][1]; } else if (!m1[1] && !m2[1]) { return Math.min(left.length - m1[0][1] + right.length, left.length + right.length - m2[0][1]) } else { return Math.min(left.length - m1[0][1] + right.length - m2[1][1], left.length - m1[1][1] + right.length - m2[0][1]) } } */ } } // 统计元素出现次数 function getCount(arr) { let m = new Map(); for (let item of arr) { m.has(item) ? m.set(item, m.get(item)+1) : m.set(item, 1); } // 这里可以用 [...m.entries()]代替,但是牛客js v8好像不行 let res = []; for (let [k, v] of m) { res.push([k,v]); } return res.sort((a, b) => b[1] - a[1]); } // test const n = 6; let arr = [1,1,4,5,1,1]; console.log(fn(n, arr)); // 3