3.27网易实习笔试(前端)

只讲编程题,意向前端,我用的javascript
第1题,一组数据,判断能组成三角形最多的数,如果有多个,都写下来
思路,从小到大排序,三重循环暴力,通过70%案例
let n = parseInt(readline());
let arr = readline().split(' ').map((a) => parseInt(a)).sort((a, b) => a - b);
let canComTri = new Array(n).fill(0);
for (let i = 0; i < n - 2; i++) {
    for (let j = i + 1; j < n - 1; j++) {
        for (let k = j + 1; k < n; k++) {
            if (arr[k] < arr[i] + arr[j]) {
                canComTri[i]++;
                canComTri[j]++;
                canComTri[k]++;
            } else {
                break;
            }
        } 
    }
}
let res = [];
let max = Math.max(...canComTri);
for (let i = 0; i < n; i++) {
    if (canComTri[i] === max) res.push(arr[i]);
}
console.log(res.join(' '))
优化方案更新,两次三重循环,三重循环优化后时间复杂度由O(N^3)降为O(N^2),第3重循环的数k与第2重j相关,因此降低了时间复杂度


let n = parseInt(readline());
let arr = readline()
  .split(" ")
  .map((a) => parseInt(a))
  .sort((a, b) => a - b);
let canComTri = new Array(n).fill(0);
for (let i = 0; i < n - 2; i++) {
  let k = i + 2;
  for (let j = i + 1; j < n - 1; j++) {
    for (k = k > j ? k : j + 1; k < n && arr[k] < arr[i] + arr[j]; k++) {}
    canComTri[i] += k - j - 1;
    canComTri[j] += k - j - 1;
  }
}

for (let i = n - 1; i >= 2; i--) {
  let k = i - 2;
  for (let j = i - 1; j >= 1; j--) {
    for (k = k < j ? k : j - 1; k >= 0 && arr[i] < arr[j] + arr[k]; k--) {}
    canComTri[i] += k - j - 1;
  }
}
let res = [];
let max = Math.max(...canComTri);
for (let i = 0; i < n; i++) {
  if (canComTri[i] === max) res.push(arr[i]);
}
console.log(res.join(" "));
第2题,给你一个二叉树,实现固定值和的路径,优先层数低的,排在左边的


思路:BFS,由于输入是数组,进行字符串切割,进行BFS遍历各点的和,和为想要的固定值,倒推路径,通过70%案例
let arr = readline().split('[')[1].split(']')[0].split(',').map((a) => parseInt(a));
const sum = parseInt(readline());
const n = arr.length;
let index;
let res = [...arr];
for (let i = 1; i < n; i++) {
    if (isNaN(res[i])) {
        continue;
    } else {
        res[i] += res[((i - 1) >> 1)];
        if (res[i] === sum) {
            index = i;
            break;
        }
    }
}
if (index) {
    let path = [arr[index]];
    while (index) {
        index = ((index - 1) >> 1);
        path.unshift(arr[index]);
    }
    console.log('[' + path.join(',') + ']');
} else {
    console.log([]);
}
优化方案
let arr = readline().split('[')[1].split(']')[0].split(',').map((a) => parseInt(a));
const sum = parseInt(readline());
const n = arr.length;
let index;
let res = [...arr];
let queue = [];
if (!isNaN(res[0])) {
    queue.push(0);
}
while (queue.length) {
    const len = queue.length;
    for (let i = 0; i < len; i++) {
        let cur = queue.shift();
        if (!isNaN(res[cur * 2 + 1])) {
            queue.push(cur * 2 + 1);
            res[cur * 2 + 1] += res[cur];
            if (res[cur * 2 + 1] === sum) {
                index = cur * 2 + 1;
                break;
            }
        }
        if (!isNaN(res[cur * 2 + 2])) {
            queue.push(cur * 2 + 2);
            res[cur * 2 + 2] += res[cur];
            if (res[cur * 2 + 2] === sum) {
                index = cur * 2 + 2;
                break;
            }
        }
    }
    if (index) break;
}
if (index) {
    let path = [arr[index]];
    while (index) {
        index = ((index - 1) >> 1);
        path.unshift(arr[index]);
    }
    console.log('[' + path.join(',') + ']');
} else {
    console.log([]);
}
第3题,一组数据,找出能组成和被6整除的最大值对应的集合
思路:想到DFS暴力,觉得不对,pass了,做问答题时想到了按模6分组,每组排序,回来想写,发现写不了,无语了,问答题也写不了,只能提前交卷
其实应该用动态规划,dp[i][n]表示前i个数模6余n的最大值,先求出最大和再经过反向遍历求出该集合

第4题,编辑距离变种,定义了编辑距离和两组字符串长度的比值,参考 https://leetcode-cn.com/problems/edit-distance/ ,只不过增删距离为1,改距离为2
思路:动态规划,dp[i][j]为字符串前i个字符子串到字符串前j个字符子串的编辑距离,可以压缩空间,笔试就不装逼了,面试被问到的话打算写好后口述优化思路,终于A了1道,感觉自己好菜
let str0Arr = readline().split('');
let str1Arr = readline().split('');
const len0 = str0Arr.length;
const len1 = str1Arr.length;
const dp = new Array(len0 + 1);
dp[0] = new Array(len1 + 1);
for (let j = 0; j <= len1; j++) {
    dp[0][j] = j;
}
for (let i = 1; i <= len0; i++) {
    dp[i] = new Array(len1 + 1).fill(Number.MAX_SAFE_INTEGER);
    dp[i][0] = i;
}
for (let i = 1; i <= len0; i++) {
    for (let j = 1; j <= len1; j++) {
        if (str0Arr[i - 1] === str1Arr[j - 1]) {
            dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - 1], dp[i - 1][j] + 1, dp[i][j - 1] + 1);
        } else {
            dp[i][j] = Math.min(dp[i][j], dp[i - 1][j] + 1, dp[i][j - 1] + 1);
        }
    }
}
let sim = (len0 + len1 - dp[len0][len1]) / (len0 + len1);
console.log(sim.toFixed(2));

优化空间,从O(MN)降至O(N)
let str0Arr = readline().split('');
let str1Arr = readline().split('');
const len0 = str0Arr.length;
const len1 = str1Arr.length;
// const dp = new Array(len0 + 1);
// dp[0] = new Array(len1 + 1);
const dp = new Array(len1 + 1);
for (let j = 0; j <= len1; j++) {
    // dp[0][j] = j;
    dp[j] = j;
}
// for (let i = 1; i <= len0; i++) {
//     dp[i] = new Array(len1 + 1).fill(Number.MAX_SAFE_INTEGER);
//     dp[i][0] = i;
// }
for (let i = 1; i <= len0; i++) {
    let pre = dp[0];
    dp[0] = i;
    for (let j = 1; j <= len1; j++) {
        let temp = dp[j];
        if (str0Arr[i - 1] === str1Arr[j - 1]) {
            // dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - 1], dp[i - 1][j] + 1, dp[i][j - 1] + 1);
            dp[j] = Math.min(pre, dp[j] + 1, dp[j - 1] + 1);
        } else {
            // dp[i][j] = Math.min(dp[i][j], dp[i - 1][j] + 1, dp[i][j - 1] + 1);
            dp[j] = Math.min(dp[j] + 1, dp[j - 1] + 1);
        }
        pre = temp;
    }
}
let sim = (len0 + len1 - dp[len1]) / (len0 + len1);
console.log(sim.toFixed(2));

自己水平有限,希望对大家有用。
前两题已更新优化方案,求大佬们指点。
#实习##笔经##网易##前端工程师#
全部评论
请问一下是网易互娱还是雷火还是其他的?
点赞 回复 分享
发布于 2021-03-28 11:05
大哥学前端多久了
点赞 回复 分享
发布于 2021-03-28 13:27
这个笔试题,我刚好做了全解析,感兴趣的可以看下哦~ https://mp.weixin.qq.com/s?__biz=MzI4MzUxNjI3OA==&mid=2247488066&idx=1&sn=5e2c82b324c8ca63e0071cd5405c71a8&chksm=eb88de5bdcff574da03bc95fce53f37b2795ba635496cdb2ddfcea34a8305d2401c48d89e414&token=1873896266&lang=zh_CN#rd
点赞 回复 分享
发布于 2021-03-28 13:52
第一题我也暴力了  但是只a了10    感谢大大 第三题感觉还是没看懂你的意思🤭 想伸手要一个代码
点赞 回复 分享
发布于 2021-03-30 09:40

相关推荐

点赞 评论 收藏
分享
评论
4
21
分享
牛客网
牛客企业服务