1、递归的定义和理解
函数内部调用函数自身,达到某个条件之后,停止调用
- 递归是一种较为 高级的编程技巧,通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解 。
2、斐波那契数列(递归法)---时间复杂度为 2n
斐波那契数列是这样的数列:
1,1,2,3,5,8,13,21。求第 n 项的斐波那契数列
找规律:
- 第 1 项=1
- 第 2 项=1
- 第 3 项是=第 1 项+第 2 项
- 第 4 项= 第 2 项+第 3 项
- 依次类推,后面每一项都等于前两项之后
求出第 n 项的值
- 递归出口: n=1 时和 n=2 时分别返回 1 2
- 递归模式:f(n)=f(n-1) +f(n-2)
求出 n 项的斐波那契数列
- 利用 for 循环结合递归,把每一项的值计算得到,然后拼接成字符串
function fibonacci(n) {
if (n == 1) return 1;
if (n == 2) return 2;
return fibonacci(n - 1) + fibonacci(n - 2)
}
console.log(fibonacci(30))
var result = ''
for (i = 1; i <= 30; i++) {
if (i == 30) {
result += `${fibonacci(i)}`
} else {
result += `${fibonacci(i)}` + ' ,'
}
}
console.log(result)
2、斐波那契数列优化版(双指针、字符串拼接)- 时间复杂度为 O(n),空间复杂度为 O(n)
思路:
- 用两个变量分别来记录当前循环的前两项(n1,n2)
- 然后定义一个变量(temp)来计算当前项得结果,然后再更新下前两项的值,以便下一轮循环用到
function fibonacci(n) {
var n1 = 1;
var n2 = 1;
var item; //临时存储每一项值
var str = ''
if (n == 1) str = '1'
if (n == 2) str = '1,1'
for (var i = 3; i <= n; i++) {
// 当前值
item = n1 + n2;
// 指针右移
n1 = n2;
n2 = item;
str += ',' + item;
}
return '1,1'+ str;
}
console.log(fibonacci(1000));
3.数组的深克隆
- 在调用函数时,传入一个数组,然后就克隆一个和传入数组一模一样的数组出来。
- 这两个数组只是长得一样,但是两个完全独立的数组,互不干扰。即两个数组指向堆内存中的不同地址。
- 时间复杂度为 O(n),只有一层 for 循环,其输入量与执行次数成正比
- 空间复杂度为 O(n),返回结果数组会受输入量的影响,输入量越大,返回结果数组越大
function deepClone(arr) {
// 判断是否是数组
if (!Array.isArray(arr)) return
var result = [];
for (var i = 0; i < arr.length; i++) {
// 如果是基本数据类型,直接push到数组中
if (Array.isArray(arr[i])) {
// 如果是数组,返回的数组要push到上一个数组中去
result.push(deepClone(arr[i]))
} else {
result.push(arr[i])
}
}
return result;
}
var arr = [1, 2, 3, ["A", "B", ["我", "和", "你"]]];
var arr1 = deepClone(arr); // 克隆数组
console.log(arr1 === arr);
arr1[3][2][0] = 1; // 更改数组中元素
console.log(arr1);