前端手撕代码(bigo三面)

228 阅读2分钟

前端手撕代码(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语言红书里面都有。