剑指Offer解题报告(Java版)——不用加减乘除做加法 47

?
?

引言

?
?

一般这种不能用四则运算的题都只有用位运算来做,目的是加强大家对计算机计算的理解,真是有点扯淡呢

?
?

解决问题

?
?

首先我们得思考计算机是怎样做加法的呢,比如3加4,如果转换成二进制是0011和0100,加起来是7,也就是0111,相当于是两个二进制的异或运算

?
?

但是我们再举一个例子就是4加4,会发现,两个二进制是0100和0100,异或运算的话结果为0000,但是我们想要的是1000,这是因为异或运算没有考虑到进位的问题,看来我们还要用一个运算去考虑进位的问题,还记得进位是怎样算的吗,如果两个树相同位上都是1,那么就是要进位,这实际上就是与操作

?
?

而最后我们需要把进位和没考虑进位的sum加起来,这里又不能用到sum,摔,此时我们又要用到之前讲的与和异或操作,这里我们取巧,就把sum赋值给n1,把carry赋值给n2,去算,停止的条件是n2==0,也就是没有进位了

?
?

static int add(int n1,int n2){

int sum=0;

int carry=0;

do {

sum=n1^n2;

carry=(n1&n2)<<1;

n1=sum;

n2=carry;

} while (n2!=0);

return sum;

时间: 2024-10-12 12:18:22

剑指Offer解题报告(Java版)——不用加减乘除做加法 47的相关文章

剑指Offer解题报告(Java版)——排序数组中某个数的个数 38

? ? 分析问题 ? ? 问题只需要找到排序数组中某个数K的个数,由于已经是排序了,K一定是在一堆的,所以我们只需要找到第一个K的index1,然后找到最后一个K的index2就可以了 ? ? 而寻找K的过程我们一般通过二分法查找,这样时间复杂度能降到logn ? ? 解决问题 ? ? 我们通过二分法寻找k,如果中间的数小于k,那么在前半段找k:如果中间的数大于k,那么在后半段找k,那么如何判断找到的k是否是一堆k的边界呢 ? ? 找第一个k的时候判断方式如下: 如果中间的数等于k,那么先判断前

剑指Offer解题报告(Java版)——字符串转换为数字 49

? ? 引言 ? ? STOI是很常见的一道题,leetcode上也有,字符串转换为数字一般都会有现成的函数去实现这样的功能,但有时候需要我们理解其中的具体实现,因为虽然是个很常见的问题,但实际上需要考虑的问题还是很多的,尤其是corner case的处理,而这类问题一般要考虑两点:一点是符号,另外一点是越界 ? ? 分析问题 ? ? 如果字符串前面有空格怎么办,一般来说中间是没有空格的,但是前后可能有空格,所以我们首先需要去掉多余的空格字符,用到trim函数 ? ? 然后就是字符串中有可能第一

剑指Offer解题报告(Java版)——约瑟夫环 45

? ? 引言 ? ? 常见的约瑟夫环问题有用循环链表做的,有用数组做的,这里提供一个用数学公式做的,由此可见,很多计算机的问题如果最终用到数学的知识,时间复杂度会大大的降低 ? ? 分析问题 ? ? 首先我们对0到n-1删除第一个数进行分析,第一个被删除的数一定是序号为m-1的数,因为0号数了1,1号数了2,m-1号数了m,那么应该删掉m-1号,设m-1号是第k号,这里这样做是因为后面可以扩展,想扩展为m-1%n=k ? ? 剩下的数按照序列重排序如下 ? ? 因为删掉的是k,那么下面第一个就是

剑指Offer解题报告(Java版)——扑克牌顺子 44

? ? 分析问题 ? ? 这个题目的关键点在于大小王可以看作任意的数字,那么我们就把这个任意的数字看作0也未尝不可,因为扑克牌中1-15都有数字,所以可以用0代表大小王 ? ? 这样我们就将问题转换成了从0-15中抽5个数字,看是否连续的问题,由于0可以看作任意数字,所以我们可以用0去补那些空缺的数,比如0,1,3也算是连续的 ? ? 要记住关键点还是这个任意数字上,考虑一个问题,就是如果这5个数中0的个数大于等于空缺数,那么坑一定能补上,所以一定是连续的,如果0的个数小于空缺数,那么0的个数不

剑指Offer解题报告(Java版)——n个骰子的点数 43

问题 ? ? n个骰子朝上的数之和为s,求s的所有可能以及概率 ? ? 分析问题 ? ? 如果是用笨方法,一般人最开始都会想到笨方法,那就是枚举法 ? ? 举个例子,比如两个骰子,第一个骰子的结果为1,2,3,4,5,6,两个骰子的结果是2,3,4,5,6,7:3,4,5,6,7,8:4,5,6,7,8,9:--7,8,9,10,11,12,共三十六种,用n平方size的数组记录这36个结果 ? ? 仔细分析可以发现其实这其中有很多是重复的,所以去除重复,考虑最小的应该是2,也就是n,最大的应该

剑指offer python版 不用加减乘除做加法

def add(n,m): while m: summ=n^m carry=(n&m)<<1 m=carry n=summ return n print(add(3,4)) 原文地址:https://www.cnblogs.com/xzm123/p/9871390.html

不用加减乘除做加法 47

先将两个数按二进制规则不考虑进位,直接相加,相当于按位异或 ? ? 然后计算进位,相当于按位与 ? ? 然后当不存在进位的时候计算完成 ? ? 如果存在进位那么将进位和没有算进位的sum再继续计算 ? ? ? ? package add47; ? ? public class Add47 { static int add(int n1,int n2){ int sum=0; int carry=0; do { sum=n1^n2; carry=(n1&n2)<<1; n1=sum; n

剑指Offer面试题47(Java版):不用加减乘除做加法

题目:写一个函数,求两个整数之和,要求在函数体内不得适用+,-,* ,./  四则运算符号 面试的时候被问道这个问题,首先我们分析人们是如何进行十进制的加法的,比如是如何得出5+17=22的结果的,实际上,我们可以分三步进行:第一步只做各位相加不进位,此时相加的结果是12,第二步做进位,5+7中有进位,进位的值为10:第三步,把前面的两个结果加起来12+10的结果是22,刚好5+17=22 我们一直在想,求两个树之和四则运算都不能用,还能用什么?对数字做运算,除了四则运算之外,也就只剩下位运算了

【剑指offer】不用加减乘除做加法

转载请注明出处:http://blog.csdn.net/ns_code/article/details/27966641 题目描述: 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. 输入: 输入可能包含多个测试样例.对于每个测试案例,输入为两个整数m和n(1<=m,n<=1000000). 输出: 对应每个测试案例,输出m+n的值. 样例输入: 3 4 7 9 样例输出: 7 16 思路: 1.先将各bit位相加,不计进位,这一步可以用m^n实现 2.加上进位