leetcode — JavaScript专题(二):记忆函数、蜗牛排序、扁平化嵌套数组、数组归约运算、函数防抖

专栏声明:只求用最简单的,容易理解的方法通过,不求优化,不喜勿喷

2623. 记忆函数

题面

请你编写一个函数,它接收另一个函数作为输入,并返回该函数的 记忆化 后的结果。

记忆函数 是一个对于相同的输入永远不会被调用两次的函数。相反,它将返回一个缓存值。

你可以假设有 3 个可能的输入函数:sum 、fib 和 factorial 。

sum 接收两个整型参数 a 和 b ,并返回 a + b 。
fib 接收一个整型参数 n ,如果 n <= 1 则返回 1,否则返回 fib (n - 1) + fib (n - 2)。
factorial 接收一个整型参数 n ,如果 n <= 1 则返回 1 ,否则返回 factorial(n - 1) * n 。

知识点:

Map

思路

我们将我们传入的参数记录下来,记录方式是将我们拿到的参数列表用 join 函数连接成一个 string,然后用这个 string 作为我们的 key,函数的调用结果作为我们的 value,将结果存在 map 中,每次调用时,我们先判定对应的 key 是不是已经存在了,如果存在直接返回;如果不存在我们新增一条内容

代码
function memoize(fn) {
    
    
    const m = new Map();
    return function(...args) {
    
    
        let p = args.join(",");
         if(!m.has(p)){
    
    
            m.set(p,fn(...args));
        }
        return m.get(p); 
    }
}


/** 
 * let callCount = 0;
 * const memoizedFn = memoize(function (a, b) {
 *	 callCount += 1;
 *   return a + b;
 * })
 * memoizedFn(2, 3) // 5
 * memoizedFn(2, 3) // 5
 * console.log(callCount) // 1 
 */

2624. 蜗牛排序

题面

请你编写一段代码为所有数组实现 snail(rowsCount,colsCount) 方法,该方法将 1D 数组转换为以蜗牛排序的模式的 2D 数组。无效的输入值应该输出一个空数组。当 rowsCount * colsCount !==nums.length 时。这个输入被认为是无效的。

蜗牛排序从左上角的单元格开始,从当前数组的第一个值开始。然后,它从上到下遍历第一列,接着移动到右边的下一列,并从下到上遍历它。将这种模式持续下去,每列交替变换遍历方向,直到覆盖整个数组。例如,当给定输入数组 [19, 10, 3, 7, 9, 8, 5, 2, 1, 17, 16, 14, 12, 18, 6, 13, 11, 20, 4, 15] ,当 rowsCount = 5 且 colsCount = 4 时,需要输出矩阵如下图所示。注意,矩阵沿箭头方向对应于原数组中数字的顺序

知识点:

数组

思路

和 js 关系不大,直接按照规律遍历即可

代码
/**
 * @param {number} rowsCount
 * @param {number} colsCount
 * @return {Array<Array<number>>}
 */
Array.prototype.snail = function (rowsCount, colsCount) {
    
    

    let re = [];

    for (var i = 0; i < rowsCount; i++) {
    
    
        let t = new Array(colsCount).fill(0);
        re.push(t);
    }
    let now = 0;
    if( rowsCount * colsCount != this.length){
    
    
        return  [];
    }
    for (var j = 0; j < colsCount; j++) {
    
    
        for (var i = 0; i < rowsCount; i++) {
    
    
            if (j % 2 == 0) {
    
    
                re[i][j] = this[now++];
            } else {
    
    
                re[rowsCount - 1 - i][j] = this[now++];
            }
        }
    }
    return re;

}

/**
 * const arr = [1,2,3,4];
 * arr.snail(1,4); // [[1,2,3,4]]
 */

2625. 扁平化嵌套数组

题面

请你编写一个函数,它接收一个 多维数组 arr 和它的深度 n ,并返回该数组的 扁平化 后的结果。

多维数组 是一种包含整数或其他 多维数组 的递归数据结构。

数组 扁平化 是对数组的一种操作,定义是将原数组部分或全部子数组删除,并替换为该子数组中的实际元素。只有当嵌套的数组深度大于 n 时,才应该执行扁平化操作。第一层数组中元素的深度被认为是 0。

请在没有使用内置方法 Array.flat 的前提下解决这个问题。

知识点:

数组、深度优先搜索

思路

深度优先搜索,维护当前的遍历深度,对于每次遍历,如果遍历传入的数组,如果遇到数字,直接填入结果,如果遇到数组,如果没用到我们限定的层数就继续遍历,维护的层数 + 1,否则直接填入结果

代码
/**
 * @param {any[]} arr
 * @param {number} depth
 * @return {any[]}
 */
var flat = function (arr, n) {
    
    
    let dfs = (level, arr) => {
    
    
        let re = [];
        for (var i = 0; i < arr.length; i++) {
    
    
            if (typeof arr[i] == "number") {
    
    
                re.push(arr[i]);
            } else {
    
    
                if(level < n){
    
    
                    re.push(...dfs(level + 1, arr[i]))
                }else{
    
    
                     re.push(arr[i])
                }
            }
        }
        return re;
    }
    return  dfs(0,arr);
};

2626. 数组归约运算

题面

请你编写一个函数,它的参数为一个整数数组 nums 、一个计算函数 fn 和初始值 init 。返回一个数组 归约后 的值。

你可以定义一个数组 归约后 的值,然后应用以下操作: val = fn(init, nums[0]) , val = fn(val, nums[1]) , val = fn(val, arr[2]) ,… 直到数组中的每个元素都被处理完毕。返回 val 的最终值。

如果数组的长度为 0,它应该返回 init 的值。

请你在不使用内置数组方法的 Array.reduce 前提下解决这个问题。

知识点:

数组

思路

遍历数组,对每一位调用传入的函数即可

代码
var reduce = function (nums, fn, init) {
    
    
    for (var i = 0; i < nums.length; i++) {
    
    
        init = fn(init,nums[i]);
    }
    return init;
};

2627. 函数防抖

题面

请你编写一个函数,接收参数为另一个函数和一个以毫秒为单位的时间 t ,并返回该函数的 函数防抖 后的结果。

函数防抖 方法是一个函数,它的执行被延迟了 t 毫秒,如果在这个时间窗口内再次调用它,它的执行将被取消。你编写的防抖函数也应该接收传递的参数。

例如,假设 t = 50ms ,函数分别在 30ms 、 60ms 和 100ms 时调用。前两个函数调用将被取消,第三个函数调用将在 150ms 执行。如果改为 t = 35ms ,则第一个调用将被取消,第二个调用将在 95ms 执行,第三个调用将在 135ms 执行。

知识点:

防抖

思路

我们为传入的函数设定一个计时器,在一定延迟后执行它,如果在这段时间内再次调用了这个函数,那么清除原先的计时器,重新开始计时,这样就会只有一定时间内的最后一个函数会被调用

代码
var debounce = function(fn, t) {
    
    
    let timer = null;
    return function(...args) {
    
    
        clearTimeout(timer);
        timer = setTimeout(() => {
    
    
            fn(...args);
        },t);   
    }
};

/**
 * const log = debounce(console.log, 100);
 * log('Hello'); // cancelled
 * log('Hello'); // cancelled
 * log('Hello'); // Logged at t=100ms
 */

猜你喜欢

转载自blog.csdn.net/weixin_46463785/article/details/130341265