牛客题解 | 不用加减乘除做加法

news/2025/2/25 15:56:42/文章来源:https://www.cnblogs.com/wc529065/p/18736517

题目

题目链接

题目的主要信息:
  • 题目给出两个数字
  • 我们需要给出两个数字相加的结果
  • 题目要求我们不可以用加减乘除符号
  • 因此与或非运算就是我们可以用的方式
举一反三:

学习完本题的思路你可以解决如下题目:

JZ15. 二进制中1的个数

JZ56. 数组中只出现一次的两个数字

JZ64. 求1+2+3+...+n

方法一:位运算非递归(推荐使用)

知识点:位运算

计算机的数字由二进制表示,我们平常的运算是对整个数字进行运算,但是还可以按照二进制的每一位分别进行运算。常见运算有位与、位或、移位、位异或等。

思路:

由于题目禁止我们使用+,-,*,/运算符,我们需要通过位运算来实现加法。我们需要通过循环迭代两个变量实现,一个变量指代进位,一个变量指代非进位。

位运算中两数进行异或运算可以提供两数加和后二进制非进位信息,位运算中的两数进行与运算的结果可以提供两数加和后的二进制进位信息。因此我们将两数与运算的结果进行循环左移一位,并在下一轮循环中继续将移位后的进位结果和非进位结果求和,重复此过程,直到不再产生进位为止。

具体做法:

  • step 1:两数进行与运算可以产生进位的信息
  • step 2:运算后执行左移1位就是每轮需要进位的方案
  • step 3:两数进行异或运算可以产生非进位的加和结果
  • step 4:将移位后的进位结果与非进位结果继续重复 step 1 - step 3 的步骤,直到不再产生进位为止

图示:

非递归

Java实现代码:

public class Solution {public int Add(int num1,int num2) {// add表示进位值int add = num2;         // sum表示总和       int sum = num1;                // 当不再有进位的时候终止循环while(add != 0) {              // 将每轮的无进位和与进位值做异或求和int temp = sum ^ add;      // 进位值是用与运算产生的add = (sum & add) << 1;    // 更新sum为新的和sum = temp;                }return sum;}
}

C++实现代码:

class Solution {
public:int Add(int num1, int num2) {// add表示进位值int add = num2;         // sum表示总和       int sum = num1;                // 当不再有进位的时候终止循环while(add != 0) {              // 将每轮的无进位和与进位值做异或求和int temp = sum ^ add;      // 进位值是用与运算产生的add = (sum & add) << 1;    // 更新sum为新的和sum = temp;                }return sum;}
};

Python实现代码:

class Solution:def Add(self , num1: int, num2: int) -> int:# add表示进位值add = num2# sum表示总和sum = num1# 当不再有进位的时候终止循环while add:# 将每轮的无进位和与进位值做异或求和temp = sum ^ add# 进位值是用与运算产生的add = (sum & add) << 1# 更新sum为新的和(处理负数问题)sum = temp & 0xFFFFFFFF return sum if sum >> 31 == 0 else sum - 4294967296

复杂度分析:

  • 时间复杂度:\(O(log(max(num1, num2)))\),因为考虑二进制之后其实在原数字的基础上求了对数,循环的次数也和二进制位数相关
  • 空间复杂度:\(O(1)\),没有额外引入空间
方法二:位运算递归(扩展思路)

知识点:位运算

计算机的数字由二进制表示,我们平常的运算是对整个数字进行运算,但是还可以按照二进制的每一位分别进行运算。常见运算有位与、位或、移位、位异或等。

思路:

由于题目禁止我们使用+,-,*,/运算符,我们需要通过位运算来实现加法。我们需要通过循环迭代两个变量实现,一个变量指代进位,一个变量指代非进位。

位运算中两数进行异或运算可以提供两数加和后二进制非进位信息,位运算中的两数进行与运算的结果可以提供两数加和后的二进制进位信息。因此我们将两数与运算的结果进行循环左移一位,并在下一轮循环中继续将移位后的进位结果和非进位结果求和,重复此过程,直到不再产生进位为止。

在递归中我们让num2承载进位信息,让num1承载加和信息,进行递归。

具体做法:

  • step 1:以num2承接是否有进位的工作,num1作为加和的结果
  • step 2:首先判断num2是否有进位
  • step 3:如果有进位则递归调用函数,并将num1更新为或运算的结果,num2更新为与运算左移一位的结果
  • step 4:如果无进位则返回num1,因为num1一直在记录加和结果

Java实现代码:

public class Solution {public int Add(int num1,int num2) {// 递归地求和,也是判断是否有进位值,此时进位值用num2来表示,每轮的结果都存储在num1中return num2 != 0 ? Add(num1 ^ num2, (num1 & num2) << 1) : num1;}
}

C++实现代码:

class Solution {
public:int Add(int num1, int num2) {// 递归地求和,也是判断是否有进位值,此时进位值用num2来表示,每轮的结果都存储在num1中return num2 ? Add(num1 ^ num2, (num1 & num2) << 1) : num1;}
};

Python实现代码:

class Solution:def Add(self , num1: int, num2: int) -> int:# 处理负数情况(递归最深的时候)if num1 >> 31 != 0 and num2 == 0:num1 -= 4294967296# 递归return num1 if num2 == 0 else self.Add((num1 ^ num2) & 0xFFFFFFFF, (num1 & num2) << 1)

复杂度分析:

  • 时间复杂度:\(O(log(max(num1, num2)))\),因为考虑二进制之后其实在原数字的基础上求了对数,循环的次数也和二进制位数相关
  • 空间复杂度:\(O(log(max(num1, num2)))\),递归栈的深度

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/889613.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

S2-奥法-法师Mage-奥术-团体-大秘境-专精-天赋-配装-宏

S2毕业装--属性 急速>精通>全能>爆击 急速越高越好。精通的收益略微高于全能。爆击随缘。 --团本/单体天赋(更新时间2月4日)--团本/单体天赋代码 C4DAjd9IgsSkCmGQ8vOmZtyV7YGMbzCmxDMmFDjZGGTzMmBAAAAAgBCACYmZbZZZmJWAAAAAAAALDDzMzMjZYmxYmZMzMjxMG --大秘/AOE天赋…

vue贪吃蛇小游戏

偶然间跟一个前端大佬学习了一个用vue写的贪吃蛇小游戏,一个小demo 感觉挺好玩,就纪录下来了直接全代码 <template><div><div class="title" :class="isShowTitle ? titlebg : "><span>分数:{{ score }}</span></div…

S2-浩劫-恶魔猎手DH-团体-大秘境-专精-天赋-配装-宏

S2毕业装--属性 爆击>精通>急速>全能 爆击和精通越高越好。急速随缘。不要全能。 --团本/单体天赋(更新时间2月1日)--团本/单体天赋代码 CEkAAAAAAAAAAAAAAAAAAAAAAYGMzMzgZmZMmJmZGAAAAAAwsMmxMMGLzMz2sNLjZGmZBLbwysYGDzGTDmZmZwG --大秘/AOE天赋(更新时间2月1日)--…

echart地图合并,并取消边框

1.地图文件编辑mapshaper https://mapshaper.org/ 2.首先将你要合并的地图文件,添加字段标识,name同级添加,名字自定义比如“area”。 举个栗子,我要将崇明区和长兴区合并成一个新区域叫新区,那么就在两个区域下面添加 "area": "新区",3.整…

用Logseq记日报和管理文献

优缺点浅评 Logseq是一款双链笔记软件,其优点结合使用场景概括来说包括开箱即用的极简界面,非常适合用来写日报 灵活的双链,强大的PDF标注,适合构建文献库 使用markdown格式来本地存储笔记,随意备份缺点多端同步功能薄弱,我不知道有没有实现方法,反正很麻烦 没有了 然后…

Python 学习记录(5)

Scikit-Learn 数据 简单介绍:Scikit-Learn 除了完成监督学习和无监督学习之外,还提供了丰富地样本数据集、样本数据生成函数与数据处理方法。 实现机器学习算法地训练、评估与预测。 包含有样本数据集、生成样本数据、特征工程以及数据分割。处理离群值 简单介绍离群值也叫逸…

gao-ji-sou-suo

高级搜索 posted on 2023-01-16 13:14:22 | under 总结 | source 一,前言 所谓高级搜索,就是对于普通的搜索(dfs,bfs,bdfs)进行优化后得到的在空间或时间上更优的算法,比如 A*,迭代加深,IDA*,双向搜索,折半搜索之类的。 二、算法 1.迭代加深 对于一个搜索的问题,如…

csp-s2023-zong-jie

CSP-S2023总结 posted on 2023-10-24 08:16:22 | under 总结 | source day- 忘了。 考了好几场牛客模拟。 gm说只有考好才能参加noip,并让我们早点休息。 所以到家10:40就睡了。 day0 睡到10:30,起床吃饭看电视。 按照gm的要求,从12:00午睡到13:05。 13:15到了,有个不…

惊艳!200MSPS采样率,RK3588F高速AD采集与实时显示案例来了!

科技飞速发展,高速数据采集与实时显示技术成为众多领域的关键需求。今天给大家分享一个基于瑞芯微RK3588J + FPGA的高速AD采集与实时显示案例。适用开发环境如下: Windows开发环境:Windows 7 64bit、Windows 10 64bit Linux开发环境:VMware16.2.5、Ubuntu20.04.6 64bit U-B…

S2-猫德-德鲁伊Druid-野性-团体-大秘境-专精-天赋-配装-宏

S2毕业装--属性 精通>爆击>急速>全能 精通越高越好。爆击收益略微高于急速。不要全能。 --团本/单体天赋(更新时间2月4日)--团本/单体天赋代码 CcGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmZb2MzCzYmZb2YsNzMz8AzMAAAAAAbBDDYMzMamxMjZGjZYjBAAAAAAAYAAAAAAmtZWa2mZZDzMDA --大…

自我介绍+5问(朱雅子)

项目 内容这个作业属于哪个课程 软件工程导论这个作业要求在哪里 作业要求文档这个作业的目标 做好本学期学习准备,初步了解“博客园和github”两个网站,熟悉markdowm编辑模式,明确该课程我想要学习什么增强目标感- part1✨🌊 雅子系统 v1.9 🎭 身份解码器个人信息 数字…

主流数字证书有哪些?

在数字化浪潮中,数字证书作为保障网络通信安全的核心技术,已成为构建可信数字生态的“基石”。从电子商务到金融交易,从电子政务到物联网,数字证书的应用场景不断拓展,其技术形态也在持续演进。本文将深入解析主流数字证书的类型、应用场景及未来发展趋势,为读者提供全面…