典型例题: 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以后,就不需要再继续做了。
【代码】
【结果】
|