剑指Offer:JZ47 - 求1+2+3+…+n(解题思路+Java代码)

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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值