腾讯企业微信前端面试一面算法题
1、筛选出现频次最高的JS对象
一个一维数组内有多个对象,且对象可重复出现,要求写一个函数,返回出现频次最高的对象列表。
const obj1 = {};
const obj2 = {};
const arr = [obj1, obj2, obj1, obj1];
function find(arr) {
const result = [];
// …
return result;
}
console.log(find(arr));
看见这道题我的解题思路就是找到数组中的众数,所以我想到的就是统计数组中每个元素出现的次数并记录下来。
const obj1 = { a: 1 }
const obj2 = { a: 2 }
const obj3 = { a: 3 }
const arr = [obj1, obj1, obj1, obj3, obj2]
function find(arr) {let result = []const countArr = [] // 计数用数组const keyArr = [] // 去重后的数组,与上面的计数数组下标一一对应let max = 0 // 用来储存最大值// 这次循环将每个元素的出现次数统计出来了arr.forEach(item => {if (keyArr.includes(item)) {countArr[keyArr.indexOf(item)]++} else {countArr.push(1)keyArr.push(item)}})// 这次循环则是找到出现次数最多的元素,然后push进结果数组输出countArr.forEach((item, index) => {if (item > max) {max = itemresult = [keyArr[index]] // 有更大的值,替换之前的结果} else if (item === max) {result.push(keyArr[index])}})return result
}
console.log(find(arr))
上面是我当时写的代码,面试结束后我一直在想自己使用了两次循环感觉还存在优化空间,能不能一次循环就搞定呢?答案是能,下面是我优化后的代码
const obj1 = { a: 1 }
const obj2 = { a: 2 }
const obj3 = { a: 3 }
const arr = [obj1, obj1, obj1, obj3, obj2]
function find(arr) {let result = []const countArr = [] // 计数用数组const keyArr = [] // 去重后的数组,与上面的计数数组下标一一对应let max = 0 // 用来储存最大值// 这里都优化在于我在统计元素出现次数的时候就开始寻找最大值了,把寻找最大值的那次循环合并的这次循环里arr.forEach(item => {if (keyArr.includes(item)) {const keyArrIndex = keyArr.indexOf(item)const countNum = ++countArr[keyArrIndex]if (countNum > max) {max = countNumresult = [keyArr[keyArrIndex]] // 有更大的值,替换之前的结果} else if (countNum === max){result.push(keyArr[keyArrIndex])}} else {countArr.push(1)keyArr.push(item)}})return result
}
console.log(find(arr))
2、JS对象等概率乱排
对一个数组(长度>=3)进行乱序排序,要求每个元素不会落到原来的位置,且落到其他位置的概率相同。
const obj1 = {};
const obj2 = {};
const obj3 = {};
const arr = [obj1, obj2, obj3];
function sort(arr) {
// …
return arr;
}
console.log(sort(arr));
看到这道题我想到的是用洗牌算法:
先从数组末尾开始,选取最后一个元素,与数组中最后一个元素以外随机一个元素交换位置。然后再选取数组倒数第二个元素,与数组的后两个元素以外随机一个元素换位置,以此类推。这个方法就像洗牌一样将上面的牌随机插入牌堆中间。
const obj1 = { a: 1 }
const obj2 = { a: 2 }
const obj3 = { a: 3 }
const obj4 = { a: 4 }
const obj5 = { a: 5 }
const arr = [obj1, obj2, obj3, obj4, obj5]
function sort(arr) {let result = JSON.parse(JSON.stringify(arr))for (let i = arr.length - 1; i > 0 ; i--) {const random = Math.floor(Math.random() * i)const save = result[random]result.splice(random, 1, result[i])result.splice(i, 1, save)}return result
}
console.log(sort(arr))
使用es6的写法可以让代码更简洁
const obj1 = { a: 1 }
const obj2 = { a: 2 }
const obj3 = { a: 3 }
const obj4 = { a: 4 }
const obj5 = { a: 5 }
const arr = [obj1, obj2, obj3, obj4, obj5]
function sort(arr) {let result = JSON.parse(JSON.stringify(arr))for (let i = arr.length - 1; i > 0 ; i--) {const random = Math.random() * i >>> 0; // 二进制无符号右移运算[result[i], result[random]] = [result[random], result[i]] // 解构赋值}return result
}
console.log(sort(arr))
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
