JZ47-求1+2+3+…+n
题目:求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
题目中要求不能使用乘除法,等一些条件判断语句
这里分离出几种方法:
1、一个个加的方法
从1加到n
2、公式法
n*(n+1)/2
解题思路1:一个个加
- 需要使用for循环for(int i = 1 ; i <= n ; i++){sum += n;},显然不符合题目要求
- 使用递归代替for循环,递归中要判断递归退出条件,需要使用if判断,不符合题目要求
- 这里可以想到使用短路与&&或者短路或||代替if,特点是第一个条件不符合就不走第二个条件
public class Solution {
/*
//使用for循环不符合题目要求
public int Sum_Solution(int n) {
int sum = 0;
for(int i = 1 ; i <= n ; i++){
sum += i;
}
return sum;
}
*/
/*
//使用递归,用到if不符合题目要求
public int Sum_Solution(int n) {
if(n == 1) return n;
return n + Sum_Solution(n - 1);
}
*/
//使用短路与&&或者使用短路或||代替if,符合题目要求
public int Sum_Solution(int n) {
int sum = n;
//当n大于1的条件成立的时候,才会递归调用加上n-1
//使用&&
boolean flag = n > 1 && (sum += Sum_Solution(n - 1)) > 0;
//使用||
//boolean flag = n == 1 || (sum += Sum_Solution(n - 1)) > 0;
return sum;
}
}
解题思路2:计算n*(n+1)/2
-
直接计算使用到了乘和除,不符合题目要求
-
可以使用右移1位>>1来代替除以2,在将乘法转换成加法,这里需要用到计算机组成原理中两个正数相乘的方法实现
101101 (45)b
110110 (54)a
--------------
000000
101101
101101
000000
101101
101101
-----------------
100101111110 (2430)
------------------------
(1)a:110110最后一位为0,不加b;b左移1:1011010,a右移1:11011
(2)a:11011最后一位为1,加b;b左移1:10110100,a右移1:1101
(3)...
...
直到a==0结束
public class Solution {
public int Sum_Solution(int n) {
//公式n*(n+1)/2
//return n*(n+1)>>1;
//左移1位相当于除2
return sum(n,n+1)>>1;
}
//计算两个数的乘积,参考计算机组成原理两数相乘,和大佬的代码实现
private int sum(int a,int b){
int num = 0;
boolean flag;
//如果条件符合(a的最后一位为1),才执行num+=b;
flag = (a & 1) == 1 && (num += b) > 0;
//a右移,b左移
a >>= 1;
b <<= 1;
//如果a != 0,才执行 sum+=sum(a,b),进行接下来的递归
flag = (a != 0) && (num += sum(a,b)) > 0;
return num;
}
}