前端手撕代码(百度一面)

423 阅读2分钟

百度面试手撕代码:数组元素非自身乘积、异步队列、数组扁平化

刚面完百度一面,给了三道手撕代码,别家都是一道。不得不说,百度的面试在线编辑器是我用过最好用的,跟vscode一样。

题目一:数组元素非自身乘积

题目描述: 给定一个整数数组nums,返回一个数组answer,其中answer[i]等于nums中除nums[i]之外其余各元素的乘积。

要求:

  • 不要使用除法,且在O(n)时间复杂度内完成。

解题思路: 为了在不使用除法的情况下计算每个元素的非自身乘积,我们可以维护两个数组,一个用于存储每个元素左边所有元素的乘积,另一个用于存储每个元素右边所有元素的乘积。最后,将这两个乘积相乘即可得到结果。

代码实现:

function productExceptSelf(nums) {
    const n = nums.length;
    const result = new Array(n).fill(1);
    
    let leftProduct = 1;
    for (let i = 0; i < n; i++) {
        result[i] *= leftProduct;
        leftProduct *= nums[i];
    }
    
    let rightProduct = 1;
    for (let i = n - 1; i >= 0; i--) {
        result[i] *= rightProduct;
        rightProduct *= nums[i];
    }
    
    return result;
}

题目二:基于Promise的异步队列

题目描述: 基于Promise实现一个task queue,其中task可以链式调用,上一个任务执行完毕才执行下一个。

要求:

  1. task是一个用于存储异步任务的函数,可以链式调用,保证上一个任务执行完毕后才能执行下一个。
  2. run方法用于循环执行异步任务。

解题思路: 我们可以定义一个TaskQueue类,其中包含一个任务数组和一个currentPromise用于追踪当前执行的任务。每个任务可以是一个返回Promise的函数,通过链式调用添加到任务队列中。

代码实现:

class TaskQueue {
    constructor() {
        this.tasks = [];
        this.currentPromise = Promise.resolve();
    }

    task(wait, callback) {
        this.tasks.push({ wait, callback });
        return this;
    }

    run() {
        this.tasks.forEach(task => {
            this.currentPromise = this.currentPromise.then(() => {
                return new Promise((resolve, reject) => {
                    setTimeout(() => {
                        try {
                            const result = task.callback();
                            if (result instanceof Promise) {
                                result.then(resolve).catch(reject);
                            } else {
                                resolve(result);
                            }
                        } catch (error) {
                            reject(error);
                        }
                    }, task.wait || 0);
                });
            });
        });
        return this.currentPromise;
    }
}

题目三:多维数组扁平化

题目描述: 将一个多维数组扁平化为一维数组。

解题思路: 多维数组的扁平化可以通过递归、reduce()方法、for...of循环或Array.prototype.flat()方法实现。

代码实现:

function flattenArray(arr) {
    return arr.reduce((acc, item) => {
        return acc.concat(Array.isArray(item) ? flattenArray(item) : item);
    }, []);
}

const multiDimensionalArray = [1, [2, [3, [4]], 5]];
const flattenedArray = flattenArray(multiDimensionalArray);
console.log(flattenedArray); // 输出: [1, 2, 3, 4, 5]

总结

这三道题目覆盖了数组操作、异步编程和递归算法等多个方面,是技术面试中常见的手撕代码题目。