前言:本系列總結了在前端面試中可能遇到的若干算法題,不按期更新前端
最近看有同窗面試遇到了n階變態跳問題(n級臺階,每次最多容許跨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)算法
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; }
//首先根據規律,存儲前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(); }
//輸入對象 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);