4

前言:本系列总结了在前端面试中可能遇到的若干算法题,不定期更新

最近看有同学面试遇到了n阶变态跳问题(n级台阶,每次最多允许跨n步,求多少种跨越方式),下面是一个变种问题

题目:假设有n级台阶,每次最多允许跨m步(m<=n),那么有多少种跨越方式?

思路:采用自顶向下的思考方式

f(n,m) = f(n-1,m)+f(n-2,m)+...+f(n-m,m)
当m=2时,这就是一个斐波那契数列。
同时,对于n阶变态跳,即n=m时,用公式有以下特点:
f(n) = f(n-1)+f(n-2)+...+f(1);//①
f(n-1) = f(n-2)+f(n-3)+...+f(1);//②
①-② 即f(n) = 2f(n-1),可以看出n阶变态跳的结果,实际是一个等比数列,也就是f(n) = 2^(n-1)

解法1:递归算法

function f(n,m) {
    var count = 0;
    if (n == 0) {
        return 1;
    }
    if (n >= m) {
        for (var i=1; i<=m; i++) {
            count += f(n-i,m);
        }
    }else {
            count += f(n,n);
        }
    return count;
}

解法2:非递归算法

//首先根据规律,存储前m项结果,当n<m时,有f(n,m)=f(n,n)=f(n)=2^(n-1)
//接下来我们依次计算n=m+1时的结果并存入数组
//根据思路提示,第n项结果等于数组逆序前m项的和,我们截取数组迭代求和
//最后返回顶层的数据,即是f(n,m)
function f(n,m) {
    var arr = [1];
    for (var i=1; i<m;i++) {
        arr.push(Math.pow(2,i));
    }
    for (var j=m+1; j<=n; j++) {
        arr.push(arr.slice(-m).reduce((a,b) => a+b))
    }
    return arr.pop();
}

深度遍历js对象的属性名

题目:给定若干嵌套项的js对象,如下

//输入对象
var obj = {
    a: {
        b: {
            c: {
                d:'h',
                j:'l',
                o: {
                    p:'q',
                    r:'s'
                },
                t: 'u'
            }
        },
        v: {
            w: {
                x: {
                    y: 'z'
                }
            }
        }
    },
    e: {
        f: {
            i: 'k'
        },
        m: 'n'
    }
}

//输出结果,按照层数,把同一层的属性放在同一个子数组内
var result = [[a,e],[b,v,f,m],[c,w,i],[d,j,o,t,x],[p,r,y]];

解题思路:按照深度遍历所有属性即可,注意对每一层做标记

//输出结果数组
var result = [];
//递归层数,也就是属性层数
var num = 0;

function getProp(obj) {
    //获取对象的属性数组
    var keys = Object.keys(obj);
    var len = keys.length;
    for(var i=0; i<len; i++) {
        //判断属性值,如果是对象,则递归遍历
        if(typeof obj[keys[i]] == 'object') {
            /如果属性是对象,层数加一
            num++;
            //用result[num-1]存储每一层的结果,如果该层首次存储属性名称,初始化为空数组
            if(typeof result[num-1] != 'object') {
                result[num-1] = [];
            }
            result[num-1].push(keys[i]);
            getProp(obj[keys[i]]);
            //注意当一层的所有属性都遍历完之后,返回上一层
            if(i == len-1) {
                num--;
            }
        }else {
            //如果属性不是层数,那么先对层数加一,存入后再减一
            num++;
            if(typeof result[num-1] != 'object') {
                result[num-1] = [];
            }
            result[num-1].push(keys[i]);
            num--;
            if(i == len-1) {
                num--;
            }
        }
    }
}
getProp(obj);
console.log(result);

Alarak
246 声望21 粉丝