题目描述
求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
在牛客网上刷题碰到了这个,笔者在刷这题的时候抱着尝试心态,直接在函数内返回了如下:
return n*(n+1)/2
没想到居然直接通过了····,可能是js的乘除法太神奇了吧,居然没被拒绝掉,当然投机取巧肯定是行不通的:
- 方法1:
function Sum_Solution(n) {
//递归
if (n === 1) return 1;
return n + Sum_Solution(n - 1)
}
递归的代码非常简洁,但是递归存在一些缺点:
1.递归由于是函数调用自身,而函数调用是有时间和空间的消耗的:每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址以及临时变量。
2.递归中很多计算都是重复的,其本质是把一个问题分解成两个或者多个小问题,多个小问题存在相互重叠的部分,则存在重复计算。
3.调用栈可能会溢出,其实每一次函数调用会在内存栈中分配空间,而每个进程的栈的容量是有限的,当调用的层次太多时,就会超出栈的容量,从而导致栈溢出。
- 方法2:不用递归,用JS里面的一些方法
function Sum_Solution2(n) {
//建立一个含有n个1的数组
var arr = new Array(n).fill(1);
//将初始化数组[1,1,1,1...,1]构造为[1,2,3,4...,n]
var newArr = arr.map((item, index) => item + index);
//[1,2,3,4...,n]数组累加求和
var res = newArr.reduce((pre, item) => pre + item, 0);
return res;
}
- 由于不能使用for循环,可以通过new Array() 初始化一个含有n个1的数组,fill()方法是ES6新出的一个方法,可以用指定的值填充一个至多个数组元素,当传入一个值的时候,fill()方法会用这个值重写数组中的所有值。
- 使用map()方法返回一个新数组,将原来的[1,1,1,1…,1]里面的每一项加上它在数组中的下标序号,打造成为[1,2,3,4,…n]。
- 使用数组的reduce()方法累加求和。