剑指offer打卡day01:“求1+2+3+...+n“ & “不用加减乘除做加法“

牛客网剑指offer算法题打卡——day01

题1:求1+2+3+…+n

题目描述

求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

示例:

输入

5

返回值

15

解析:

  1. 如题,如果要求1+2+3+…+n的累加,最普通的代码实现应该是:

    int n = new Scanner(System.in).nextInt();
    int sum = 0;
    for (int i = 0; i <= n; i++) {
        sum += i;
    }
    
  2. 在实现过程中必须满足

    1. 递增:让数字从1到n不断递增,实现逐位累加
    2. 终止:加到目标数字n即终止
  3. 但题目说明不能用循环以及乘除法,只能用其他方式实现”递增“与”终止“,那有什么其他方法实现这两种要素呢?

    有的,递归逻辑与

    1. 递归:

      定义(条件):

      (1)需要解决的问题可以转化为一个或者多个子问题来求解,而这些子问题的求解方法与原问题相同,只是在数量和规模上不同。

      (2)递归的次数是有限的。

      (3)必须有结束递归的条件来终止递归。

      例子:

      假设我们用递归来算阶乘 f(n):

      f = n =>
          n === 1 ? 1
                  : n * f(n-1) 
      

      f 里面用到了 f,怎么理解呢?

      很简单,把式子展开即可:

      f(6)
      => 6 * f(5)
      => 6 * (5 * f(4))
      => 6 * (5 * (4 * f(3)))
      => 6 * (5 * (4 * (3 * f(2))))
      => 6 * (5 * (4 * (3 * (2 * f(1)))))
      => 6 * (5 * (4 * (3 * (2 * 1))))
      => 6 * (5 * (4 * (3 * 2)))
      => 6 * (5 * (4 * 6))
      => 6 * (5 * 24)
      => 6 * 120
      => 720
      

      该例子来源知乎,侵删。

    2. 逻辑与:

      定义:

      符号为“&&”,只有两个操作数都是真,结果才是真。

      "逻辑与"操作属于短路操作:

      1. 既如果第一个操作数能够决定结果,那么就不会对第二个操作数求值。
      2. 对于逻辑与操作而言,如果第一个操作数是假,则无论第二个操作数是什么值,结果都不可能是真,相当于短路了右边。

解答:

/*
解题思路:
利用 &&(逻辑与的短路)与递归的调用实现自增
*/
public int Sum_Solution(int n){
    int sum = n;
    boolean flag =  (num > 0) && ((num += sum_solution(n - 1))>0);
    return num;
}

题2:不用加减乘除做加法

题目描述

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

示例:

输入

1,2

返回值

3

解析:

不用算术运算符实现两个数的加法(按位异或)

对于二进制的加法运算,若不考虑进位,

则1+1=0,1+0=1,0+1=1,0+0=0,通过对比异或,不难发现,此方法与异或运算类似。因而排出进位,加法可用异或来实现。

–然后考虑进位,0+0进位为0,1+0进位为1,0+1进位为0,1+1进位为1,该操作与位运算的&操作相似。

那么加法运算可以这样实现:

  1. 先不考虑进位,按位计算各位累加(用异或实现),得到值a;

  2. 然后在考虑进位,并将进位的值左移,得值b,若b为0,则a就是加法运算的结果,若b不为0,则a+b即得结果(递归调用该函数)。

在这里插入图片描述

解答:

  1.  public int add(int num1,int num2) {
            while(num2 != 0){
                int temp = num1^num2;//相加各个位的值 异操作
                num2 = (num1&num2)<<1;//相加进位的值 与操作
                num1 = temp;
            }
            return num1;
        }
    

计算过程

补充:

异或运算的作用

a^b 如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0

按位异或的3个特点:

  1. 00=0,01=1

0异或任何数==任何数

  1. 10=1,11=0

1异或任何数 == 任何数取反

  1. 任何数异或自己 == 把自己置0

异或的运用:

  1. 实现两个值的交换,而不必使用临时变量。

     例如交换两个整数a=10100001,b=00000110的值,可通过下列语句实现:
      a = a^b;   //a=10100111
      b = b^a;   //b=10100001
      a = a^b;   //a=00000110
    
  2. 快速判断两个值是否相等

    举例1: 判断两个整数a,b是否相等,则可通过下列语句实现:

    return ((a ^ b) == 0)

  3. 扩展:

    1. 不申请额外内存实现两个变量值得交换:

      方法一:

      通过异或来实现;

      a=a^b;

      b=a^b;

      a=a^b;

      方法二:

      通过加减运算实现;

      a=a+b;

      b=a-b;

      a=a-b;

申请额外内存实现两个变量值得交换:

  方法一:

  通过异或来实现;

    a=a^b;

    b=a^b;

    a=a^b;

  方法二:

  通过加减运算实现;

    a=a+b;

    b=a-b;

    a=a-b;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值