前端手撕代码(bigo三面)
bigo三面给了两道算法题,都不难。
题目一:随机打乱数组
题目描述: 实现一个函数,随机打乱一个给定的数组,并返回原数组的打乱版本。
要求:
- 不能使用现成的库函数,如
Array.prototype.shuffle。
解题思路: 随机打乱数组的一个经典方法是Fisher-Yates洗牌算法,也称为Knuth洗牌算法。该算法通过从后向前遍历数组,并随机交换当前元素与前面任意一个元素的位置来实现。
代码实现:
function shuffleArray(array) {
const newArray = array.slice(); // 创建数组的副本以避免修改原数组
for (let i = newArray.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1)); // 生成0到i之间的随机索引
[newArray[i], newArray[j]] = [newArray[j], newArray[i]]; // 交换元素
}
return newArray;
}
// 示例
const myArray = [1, 2, 3, 4, 5];
const shuffledArray = shuffleArray(myArray);
console.log(shuffledArray); // 输出可能是 [3, 2, 1, 5, 4],每次运行结果可能不同
题目二:翻转整数
题目描述: 实现一个函数,将一个整数翻转(即数字的顺序颠倒),并返回翻转后的整数。
要求:
- 不能使用字符串或数组来辅助翻转。
- 需要处理整数溢出的情况。
解题思路: 翻转整数可以通过数学运算实现。首先,我们需要处理负数的情况,然后通过取余和整除操作逐位提取整数的最后一位,并将其添加到翻转后的整数中。最后,我们需要检查翻转后的整数是否溢出32位整数的范围。
代码实现:
function reverseInteger(num) {
let reversed = 0;
const isNegative = num < 0;
num = Math.abs(num);
while (num > 0) {
reversed = reversed * 10 + (num % 10);
num = Math.floor(num / 10);
}
if (isNegative) {
reversed = -reversed;
}
// 检查是否溢出 32 位整数范围
if (reversed < -Math.pow(2, 31) || reversed > Math.pow(2, 31) - 1) {
return 0;
}
return reversed;
}
// 示例
console.log(reverseInteger(123)); // 输出 321
console.log(reverseInteger(-123)); // 输出 -321
console.log(reverseInteger(120)); // 输出 21
console.log(reverseInteger(1534236469)); // 输出 0(溢出)
总结
这两道算法题是经典老题了,谭浩强的c语言红书里面都有。