前端场景算法题(一)

66 阅读2分钟

说明: 以下知识来源网上素材,纯属个人笔记; 如需了解可以查找原文,请勿在此纠结

1.合并区间

题目:给定多个区间,合并所有重叠的区间;

示例: 输入:[[1,3],[2,6],[8,10],[15,18]] → 输出:[[1,6],[8,10],[15,18]]

答案:

function mergeInterVals(intervals){
    if(intervals.length<=1) return intervals;
    
    intervals.sort((a,b)=> a[0]-b[0]);
    
    let merge = [intervals[0]];
    for(let i=1; i<intervals.length; i++){
        let current = intervals[i];
        let last = merge[merge.length-1];
        if(current[0]<=last[1]){
            last[1] = Math.max(last[1], current[1]);
        }else{
            merge.push(intervals[i])
        }
    }
    
    return merge
}

2.深拷贝(deep clone)

题目: 实现一个深拷贝,处理循环引用; 答案:

function deepclone(obj, map= new WeekMap()){
    if(obj === null || type obj === 'obj') return obj;
    if(obj.has(obj)) return map.get(obj);
    
    const clone = Array.isArray(obj) ? [] : {};
    for(let key in obj){
        if(obj.hasOwnProperty(key)){
           clone[key] = deepclone(obj[key], map);
        }
    }
    return clone;
}

3.实现Promise.all

题目: 手写Promise.all, 处理异步任务并触发; 答案:

function promiseAll(promises){
    return new Promise((resolve, reject)=>{
        let result = [];
        let count = 0;
        promises.forEach((promise, index)=>{
            Promise.resolve(promise).then((value)=>{
                result[index] = value;
                count ++;
                if(count === result.length){
                    resolve(result)
                }
            }).catch(reject);
        })
    })
}

4.扁平化嵌套数组

题目:将嵌套数组展开为一堆数组,支持无线层级。 示例:输入 [1, [2, , 4], 5] → 输出 [1,2,3,4,5]

答案:


方法一: Array.prototype.flat()
使用现代的JavaScript特性,如`Array.prototype.flat()`方法。`flat()`方法可以接受一个参数,表示要展开的层数,如果不确定层级深度,可以传递`Infinity`作为参数。

function flattenArr(arr){
    return arr.flat(Infinity)
}

方法二: 递归方法
function flattenArr(arr){
    let result = [];
    arr.forEach((item,index)=>{
        if(Array.isArray(item)){
            result = result.concat(flattenArr(item));
        }else{
            result.push(item)
        }
    })
    result result;
}

5. 三数之和

题目:找出数组中所有不重复的三元组,使得 a+b+c = 0;

示例:输入 [-1,0,1,2,-1,-4] → 输出 [[-1,-1,2], [-1,0,1]]

答案:

使用一个集合(例如使用 `Set`)来存储结果,以确保结果中不会有重复的三元组。

function threeSum(nums) {
    nums.sort((a, b) => a - b); // 排序数组
    const result = [];
    const seen = new Set(); // 用于存储结果三元组的字符串形式,避免重复
 
    for (let i = 0; i < nums.length - 2; i++) {
        if (i > 0 && nums[i] === nums[i - 1]) continue; // 跳过重复的元素
        let left = i + 1;
        let right = nums.length - 1;
 
        while (left < right) {
            const sum = nums[i] + nums[left] + nums[right];
            if (sum === 0) {
                const triplet = [nums[i], nums[left], nums[right]];
                const tripletStr = triplet.join(','); // 将三元组转换为字符串形式
                if (!seen.has(tripletStr)) { // 如果这个三元组之前没出现过,则添加到结果中
                    result.push(triplet);
                    seen.add(tripletStr); // 添加到已见集合中
                }
                left++; // 移动左指针
                right--; // 移动右指针
                // 跳过所有重复的元素,避免重复的三元组
                while (left < right && nums[left] === nums[left - 1]) left++;
                while (left < right && nums[right] === nums[right + 1]) right--;
            } else if (sum < 0) {
                left++; // 如果和小于0,移动左指针增大和
            } else {
                right--; // 如果和大于0,移动右指针减小和
            }
        }
    }
    return result;
}
 
// 示例使用:
const nums = [-1, 0, 1, 2, -1, -4];
console.log(threeSum(nums)); // 输出: [[-1, -1, 2], [-1, 0, 1]]