爬樓梯問題:一次只能走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;
}
}