跳至主要內容

不用加减乘除做加法

微信公众号:储凡2023/3/23大约 3 分钟

不用加减乘除做加法

题目链接

题目描述

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

数据范围:两个数都满足−10≤n≤1000

进阶:空间复杂度O(1),时间复杂度O(1)

刷题思路

方案一: 利用自增

方案二: 利用位运算


1 + 1 = 0      1 ^ 1 = 0  ##错误
1 + 0 = 1     1 ^ 0 = 1  ##正确
0 + 1 = 1     0 ^ 1 = 1  ##正确
0 + 0 = 0      0 ^ 0 = 0  ##正确

1 & 1 = 1  ##进位
1 & 0 = 0  ##不进位
0 & 1 = 0  ##不进位
0 & 0 = 0  ##不进位
  • 当前位的和值等于 A(i)^B(i)
  • 进位等于 A(i)&B(i),进位需要加在计算位的前一位,所以左移1位,即A(i)&B(i)<<1

所以找出规律 A+B=A^B+(A&B)<<1

即:函数的第一个参数接受不进位的操作结果,第二个参数接受进位操作的结果

代码实现

/**
 * 【简单】不用加减乘除做加法
 * - 利用自增
 */
function addOne(num1, num2) {
  // 整数递增
  if (num2 > 0) {
    while (num2 > 0) {
      num2--
      num1++
    }
  }

  // 负数递减
  if (num2 < 0) {
    while (num2 < 0) {
      num2++
      num1--
    }
  }
  return num1
}

/**
 * 【简单】不用加减乘除做加法
 * - 利用位运算【递归】
 */
function addTwo(num1, num2) {
  return num2 ? addTwo(num1 ^ num2, (num1 & num2) << 1) : num1
}

/**
 * 【简单】不用加减乘除做加法
 * - 利用位运算【循环】
 */
function addThree(num1, num2) {
  let result = 0
  let carry = 0
  do {
    // 不带进位的加法
    result = num1 ^ num2
    // 进位
    carry = (num1 & num2) << 1
    num1 = result
    num2 = carry
  } while (carry !== 0) // 进位不为0则继续执行加法处理进位
  return result
}

console.log(addOne(1, 2))
console.log(addTwo(3, 4))
console.log(addThree(3, 4))

一些建议

  • 注意ES6中位运算,左移<< ,右移>>
  • 循环的写法

更新日志

2024/7/29 15:43
查看所有更新日志
  • 5a2b2-feat: 移除markdown-cli模块,采用prettier校验文档格式
  • a3cca-refactor: 替换eslint规则,使用antfu/eslint模块 (#138)
  • c0f2d-refactor: 升级vuepress相关版本,优化项目结构 (#137)
  • 06596-feat: 算法相关文档新增固定链接,优化导入代码配置
  • b5563-feat: 新增一些文档,调整导航栏内容
  • 9b9e4-feat: 算法相关文档更新,删除讨论链接 (#88)
  • c374b-feat: 更新一些文档的固定链接 (#87)
  • b0275-feat(markdownlint-cli): 添加markdown文档校验,支持lint脚本自动格式化文档
  • 5f1e1-feat: 导航栏、侧边栏内容修改,新增目录对应的文档
  • 02ab1-style: 文档目录调整,修改mdEnhance配置
  • d0347-docs(algorithm): 新增模版格式
  • afe76-docs: 新增一些算法解析文档
贡献者: Chu Fan,chufan,142vip.cn,mmdapl,chufan443