67、415、2、445、989、66 给定两个字符串/链表/数组,代表两个2/10进制数,返回他们的和

典型例题: 67   给定两个二进制字符串,返回他们的和(用二进制表示)                              点击此处返回总目录

习题1、415 给定两个十进制字符串,返回他们的和

习题2、2     给定两个链表,代表两个十进制数,求他们的和(I)

习题3、445 给定两个链表,代表两个十进制数,求他们的和(II)

习题4、989  给定一个数组和一个数字,其中数组代表一个数字,求这两个数字的和

习题5、66    给定一个数组,代表一个数字。返回这个数加1的结果

 

 

例题:67 给定两个二进制字符串,返回他们的和(用二进制表示)

【题目】

 

 

【分析】

371题中,我们讲了给定两个整数,通过位运算来计算他们的和。

这个题是给了两个二进制串。如果将字符串转成整数来做,肯定能做出来,但是就没啥意思了。我们用其他的方法来做。

 

我们来模拟两个二进制相加的过程,比如"1010","101011"。

       1010

+ 101011

首先是最低位相加,0+1得0,进位为0。

然后是第2位相加,1+1=1,再加上进位0,得1。进位为0。

然后第3位相加,0+0=0,再加上进位0,得0。进位为0。

然后第4位相加,1+1=1,再加上进位0,的1。进位为1。

这样第一个字符串就到头了,只看第二个字符串。

第5位,0加上进位1,得1。进位为0。

第6位,1加上进位0,的1。进位为0。

完。

 

根据以上分析,我们可以得出,首先把本位的两个数相加,然后与进位相加。相加的结果,如果满2就进位,如果不满2就不进位。

 

即:当三数之和为sum时,结果为sum%2,进位为sum/2。

 

再比如,两个十进制相加:

     55

+ 147

首先5+7+0=12,本位得2,进位为1。

然后5+4+1=10,本位得0,进位为1。

最后1+1=2,本位的2,进位为0。

 

【代码】

 

代码简化了不少。

结果是4ms。

 

 

【改进】

我们上面都是分了两种情况:对于长度相同的部分,相加。对于一个多出来的部分,单独计算。其实这两个没有什么区别。

如果这个位置没有字符,就不加就行了。

 

代码:

 

又简单了很多。

 

【继续改进】

还可以把carry合并进去。因为当没有a,b时,1%2=1,1/2=0,也没有问题。

另外i的计算比较复杂,我们也改一下。

 

最终代码如下:

 

 

结果:

 

 

----------------------------------------------------------------------------------------------------------

习题1、415 给定两个十进制字符串,返回他们的和

 

【题目】

 

【分析】

跟上一个题一样。上一题是字符串的二进制。这个题是字符串的十进制。

本位:(a+b+carry)%10

进位:(a+b+carry)/10

 

【代码】

 

【结果】

 

--------------------------------------------------------------------------------------------------------------------

 

习题2、2  给定两个链表,代表两个十进制数,求他们的和

 

【题目】

 

【分析】

还是一模一样啊。而且刚好,从第1位加到后面,符合链表的指针指向。

 

【代码】

 

【结果】

 

----------------------------------------------------------------------------------------------------------------------

习题3、445 给定两个链表,代表两个十进制数,求他们的和(II)

 

【题目】

 

【分析】

这个题中,链表就正常了。比上一个题目增加了难度。

可以使用栈来做。我们先把两个链表中的元素存到两个栈中,这样就反过来了。就可以用前面的方法了。

 

【代码】

 

本来可以不用i,j两个变量。直接使用Stack.empty()函数判断。但是我担心会耽误时间,所以就自己判断了。

 

 

【结果】

 

 

低于10ms的代码,基本都是先翻转两个串,然后相加的。所以,我这个应该是最好的方法。

 

 

---------------------------------------------------------------------------------------------------------------------------------

习题4、989  给定一个数组和一个数字,其中数组代表一个数字,求这两个数字的和

 

【题目】

 

【方法一】

跟前面的一样,第一、二题用字符串保存数字,现在改用数组保存数字,更好算了。K的某一位也很容易求出来。

 

代码:

 

结果:

 

结果还行吧,但是差一点。

 

【方法二】

方法一,还可以,但是差一点。还能改进一下么?

答案是可以。这个题是给了一个数组和一个数,而不是给了两个数组。但是刚才用的时候,我们首先吧数字K拆成一位一位的,然后加上数组相应的位之后,最后又拆成一位一位的了。这里面有点重复劳动。

比如:

    155

+    47

我们先把47%10得到7,然后7加5,得到12,本位为2,进位为1。然后第二位5+4+1再继续做。。。

 

另外一个好的方法是:

我们可以把47当做初始进位。5+47=52,本位的2,进位为5。5+5=10,本位为0,进位为1....

 

代码:

 

结果:

 

这个方法比方法一,少了一个变量,省去了很多次判断和取余操作。结果当然更好了。

该方法充分利用了本题目的特点,一个数为K。再求和。

 

-------------------------------------------------------------------------------------------------------------------------

习题5、66    给定一个数组,代表一个数字。返回这个数加1的结果

 

【题目】

 

【分析】

这个题是上面一个题的特殊情况,即K=1。

我们不用上面的方法。我们分析一下。一个数加1,除非是9999...9这种情况下得到1000...0,其余情况都不会使位数增加。

而且,当carry变成0以后,就不需要再继续做了。

 

【代码】

 

【结果】

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值