js算法題合集(不按期更新)

前言:本系列總結了在前端面試中可能遇到的若干算法題,不按期更新前端

最近看有同窗面試遇到了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);
相關文章
相關標籤/搜索