爬楼梯问题:一次只能走1阶或2阶台阶,求到第n阶有几种走法?
典型的斐波那契数列问题,到第n阶的走法等于最后一步走1阶和走2阶的走法之和,即f(n) = f(n-1) + f(n-2);
与传统斐波那契数列(f(0) = 0, f(1) = 1, f(2) = f(0) + f(1) = 1)不同的是:其中当n = 1时,f(1) = 1;当n = 2时,f(2) = 2。
因此:
function fibonacci(n){ if(typeof n !== "number") { return false; } if(n === 0) { return 0; } var tmp = 0; var res = 1; while (n--) { res += tmp; tmp = res - tmp; } return res; }
如果现在有需求,要计算到第5步的走法和第10步的走法数量,时间复杂度是多少?需要循环多少次?
时间复杂度为O(n),分别需要循环5次与10次。
还可以继续优化吗?
如果需要频繁计算,则可以牺牲空间换取时间,可以在函数外部专门定义一个数组专门用于存储已经计算出来的走法数,那么在下次计算时先查询数组中是否存在结果,若是没有再进行计算。
var fibonacci = { fibonacciArr:[0,1,2], fibonacciCompute:function (n) { if(typeof n !== "number" || n < 0) { return false; } var len = this.fibonacciArr.length; if (n < len) { return this.fibonacciArr[n]; } var tmp = this.fibonacciArr[len-2]; var res = this.fibonacciArr[len-1]; for (var i = len; i <= n; i++) { res += tmp; tmp = res - tmp; this.fibonacciArr.push(res); } return res; } }
编写一个数组去重的方法?
若不用考虑ES6语法的兼容问题,可以使用Array.form()与Set()方法,否则使用双层循环去重。
其中
Set
对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
Array.from()
方法从一个类似数组或可迭代对象中创建一个新的数组实例。
因此:
function removeRepeat(array) { if (Array.from && Set) { return Array.from(new Set(array)); } else { var result = []; for(var i=0; i<array.length; i++){ var flag = true; for(var j=0; j<result.length; j++){ if(array[i] == result[j]){ flag = false; break; }; }; if(flag){ result.push(array[i]); }; }; return result; } }