提供可笔试考察的题目。代码阅读以代码手写
JSON.parse数组
JSON.parse("[[[2],45,6,7],6,7,8]")
// 1
function jsonParse (opt) {
return eval(`(${opt})`);
}
// 2
var json = (new Function('return ' + jsonStr))();
// 3
function jsonParse (json) {
var rx_one = /^[\],:{}\s]*$/;
var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
if (rx_one.test(json.replace(rx_two, "@").replace(rx_three, "]").replace(rx_four, ""))) {
return eval(`(${json})`);
}
}
实现 cache函数
function cache(fn){
// TO-DO
var res ={}
return function(){
var arg = arguments[0]
console.log(arg)
if(res[arg]){
console.log('走的缓存')
return res[arg]
}else{
res[arg] = fn.call(null,arg)
return res[arg]
}
}
}
function complexCal(a){
//这里有复杂计算
return a
}
var combine = cache(complexCal)
combine(1)
combine(2)
combine(1)
股票
// maxProfit([9,1,6,3,6,4] )
var maxProfit = function (prices) {
let profit = 0; // 收益
for (let i = 1; i < prices.length; i++) {
// 今天和昨天的差价 差价大于0 才能算是收益不然就是赔钱
profit += Math.max(0, prices[i] - prices[i - 1]);
}
return profit;
};
大数相加
// 缺少负数的考虑
let a = "9007199254740991";
let b = "1234567899999999999";
function add(a ,b){
//取两个数字的最大长度
let maxLength = Math.max(a.length, b.length);
//用0去补齐长度
a = a.padStart(maxLength , 0); //"0009007199254740991"
b = b.padStart(maxLength , 0); //"1234567899999999999"
//定义加法过程中需要用到的变量
let t = 0;
let f = 0; //"进位"
let sum = "";
for(let i=maxLength-1 ; i>=0 ; i--){
t = parseInt(a[i]) + parseInt(b[i]) + f;
f = Math.floor(t/10);
sum = t%10 + sum;
}
if(f == 1){
sum = "1" + sum;
}
return sum;
}
回文子串
var countSubstrings = function(s) {
// dp[i][j] 表示第i个数到第j个数是否为回文串
// dp[i][j] = (s[i] === s[j] && (j - i <= 2 || dp[i + 1][j - 1]))
// 依次以i开头的字符串,判断从i j 之间是否有回文串
let dp = new Array(s.length).fill().map(() => new Array())
console.log(dp)
let res = 0
for (let i = s.length - 1; i >= 0; i--) {
for (let j = s.length - 1; j >= i; j--) {
if (
s[i] === s[j] &&
(j - i <= 2 || dp[i + 1][j - 1])
) {
dp[i][j] = true;
}
if (dp[i][j]) res++;
}
}
console.log(dp)
return res;
};
console.log(countSubstrings('abac'))
矩阵:左上角到右下角最近距离
var minPathSum = function(grid) {
console.log(grid)
for (let i = 1; i < grid.length; i++) {
grid[i][0] = grid[i-1][0] + grid[i][0]
}
for (let i = 1; i < grid[0].length; i++) {
grid[0][i] = grid[0][i-1] + grid[0][i]
}
console.log(grid)
for (let i =1; i < grid.length; i++) {
for (let j = 1; j < grid[0].length; j++) {
grid[i][j] = Math.min(grid[i-1][j], grid[i][j-1]) + grid[i][j]
}
}
console.log(grid)
return grid[grid.length-1][grid[0].length-1]
};
const arr = [ [1, 3, 1],
[1, 5, 1],
[4, 2, 1],
];
console.log(minPathSum(arr))
八皇后变种:给定一个8x8的棋盘, 上面有若干个车 写一个函数检查这些车有没有互相攻击的情况
8x8棋盘,要求随机生成一张棋盘,值分别为1、0,1代表有车,0代表没车,并返回这张棋盘是否存在相互攻击的情况。
假设当前场景没有互相攻击,那么最多还能放置多少辆小车?有多少种放法?
let arr = [
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0],
];
function checkConflict(arr) {
let resRow = [];
let resCol = [];
// 遍历两次 寻找同一行 同一列
for (let index = 0; index < 8; index++) {
const row = arr[index].reduce((pre, item, i) => {
if (item === 1) {
return [...pre, [i, index]];
}
return pre;
}, []);
if (row.length > 1) {
resRow = [...resRow, ...row];
}
}
for (let jndex = 0; jndex < 8; jndex++) {
let _arr = Array.from({ length: 8 }).map((_, index) => {
return arr[index][jndex];
});
const col = _arr.reduce((pre, item, i) => {
if (item === 1) {
return [...pre, [jndex, i]];
}
return pre;
}, []);
if (col.length > 1) {
resCol = [...resCol, ...col];
}
}
return {
resRow,
resCol,
};
}
console.log(checkConflict(arr));
// 已知放车的行不参与遍历,每一个的落点满足两个条件 :1,行上没有车 2 列上没有车 。
八皇后变种:8x8棋盘,随机有N个车,要求获取到不被车攻击的所有点。
// 八皇后变种:8x8棋盘,随机有N个车,要求获取到不被车攻击的所有点。
// 从车开始 遍历每一个车的 上下 左右方向。把所有能攻击的坐标标记出来,剩下的就是不能被攻击的
function a(array) {
const allMap = {};
const utilArr = Array.from({ length: 8 }).fill(0);
function map(fn) {
for (let rowI = 0; rowI < array.length; rowI++) {
for (let colI = 0; colI < array[0].length; colI++) {
fn(rowI, colI);
}
}
}
map((rowI, colI) => {
// 保存所有坐标的建值对
allMap[`${rowI}${colI}`] = false;
});
map((rowI, colI) => {
// 该子是车 行列上的都标记为true
if (array[rowI][colI] === 1) {
utilArr.forEach((_, index) => {
allMap[`${rowI}${index}`] = true;
allMap[`${index}${colI}`] = true;
});
}
});
return allMap;
}
console.log(
a([
[0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0],
])
);
8x8的棋盘上,放置着若干「黑皇后」和一个「白国王」,找出能够攻击国王的皇后
function yy(queens, king) {
const result = [],
dd = [ [-1, 0], // 左
[-1, 1],// 左上
[0, 1], // 上
[1, 1], // 右上
[1, 0], // 右
[1, -1], // 右下
[0, -1], // 下
[-1, -1], // 左下
];
dd.forEach(([dx, dy]) => {
const temp = fin(dx, dy);
if (temp) result.push(temp);
});
function fin(dx, dy) {
// 要check的坐标坐标
let posX = king[0],
posY = king[1];
do {
posX += dx;
posY += dy;
// 移动一格后的坐标
if ( // 坐标上🈶️queen
queens.find((queen) => {
return queen[0] === posX && queen[1] === posY;
})
) {
return [posX, posY];
}
} while (posX >= 0 && posX <= 8 && posY >= 0 && posY <= 8);
return null;
}
return result;
}
console.log(
yy(
[
[0, 1],
[1, 0],
[4, 0],
[0, 4],
[3, 3],
[2, 4],
],
[0, 0]
)
);
数组降纬
// 降纬
function flat(arr){
return Array.isArray(arr) ? arr.reduce((pre,item)=>([...pre,...flat(item)]),[]) : [arr]
}
console.log(flat([1, [[2], [3, [4]], 5]]))
代码执行
function F() {};
F.a = 100;
F.prototype.b = 10;
let z = new F();
console.log(z.a); // undefined
console.log(z.b); // 10
function fun(n, k) {
console.log(k);
return {
fun: function (m) {
return fun(m, n);
},
};
}
var a = fun(0); // undefined
a.fun(1); // 0
a.fun(2); // 0
a.fun(3); // 0
var b = fun(0).fun(1).fun(2).fun(3); // undefined 0 1 2
var c = fun(0).fun(1); // undefined 0
c.fun(2); // 1
c.fun(3); // 1
树遍历
深度遍历-递归
var recursiveTraverse = function (node, action) {
if (!node || !node.children) { return; }
action(node.value);
node.children.forEach(function(item, index) {
recursiveTraverse(item, action);
});
}
// 递归实现
recursiveTraverse(tree, console.log);
var nonRecursiveDepthFirstTraversal = function (node, action) {
if (!node || !node.children) { return; }
var _stack = []; // 借助一个栈
_stack.unshift(node);
while (_stack.length) {
let _curNode = _stack.shift(); // 推出栈顶元素
action(_curNode.value);
// 将子节点依次放入到栈顶
// _curNode.children.forEach(function (item, index) {
// _stack.unshift(item);
// })
if (_curNode.children.length) {
_stack = _curNode.children.concat(_stack);
}
}
}
// 非递归深度优先遍历
nonRecursiveDepthFirstTraversal(tree, console.log);
var nonRecursiveWidthFirstTraversal = function (node, action) {
if (!node || !node.children) { return; }
var _queue = []; // 借助一个队列
_queue.push(node);
while (_queue.length) {
let _curNode = _queue.shift(); // 推出队头元素
action(_curNode.value);
// 将子节点依次推入队列中
// _curNode.children.forEach(function (item, index) {
// _queue.push(item);
// })
if (_curNode.children.length) {
_queue = _queue.concat(_curNode.children);
}
}
}
// 非递归宽度优先遍历
nonRecursiveWidthFirstTraversal(tree, console.log);