lintcode 中等题:A + B Problem A + B 问题
题目:
给出两个整数a和b, 求他们的和, 但不能使用 + 等数学运算符。
如果 a=1 并且 b=2,返回3
你不需要从输入流读入数据,只需要根据aplusb的两个参数a和b,计算他们的和并返回就行。
显然你可以直接 return a + b,但是你是否可以挑战一下不这样做?
a和b都是 32位 整数么?
- 是的
我可以使用位运算符么?
- 当然可以
解题
上面提示了用位运算,通过不能够用加法,应该也会用到逻辑运算,感觉应该提取a、b的每位数据进行计算,也就是:a1 = a & 1 ,b1 = b & 1 这个就把a、b的最低位提取出来了,同时在进行下一位计算的时候a、b要右移一位,也就是 a = a>> 1 、b = b>> 1,下面问题是中间该怎么搞?参考博客。
a1、b1是a、b的对应位,carry1上一位的进位数,carry2是这一位的进位数,val是a1、b1、carry的和,计算结果有下表:
| a1 | b1 | carry1 | carry1 | val |
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 | 1 |
| 0 | 1 | 0 | 0 | 1 |
| 1 | 0 | 0 | 0 | 1 |
| 1 | 1 | 1 | 1 | 1 |
| 1 | 1 | 0 | 1 | 0 |
| 1 | 0 | 1 | 1 | 0 |
| 0 | 1 | 1 | 1 | 0 |
下面即简单又不简单
val是第i位的数,carry2是要进位的数,下一轮循环将会代替carry1
val应该在第i位,左移i位可以解决问题,val = val << i
sum 用来保存结果,初始值是 0 ,sum和val进行或运算,<只要有一个1 就是1>,在进行地位运算的时候,高位都是0,也就是主要判断val的值是不是1的问题,sum = sum | val
这里的过程还真的不好想的
下一轮循环就是 a = a >> 1 b = b >> 1
Java程序:
class Solution {
/*
* param a: The first integer
* param b: The second integer
* return: The sum of a and b
*/
public int aplusb(int a, int b) {
// write your code here, try to do it without arithmetic operators.
int sum = 0 ;
int carry = 0;
for(int i = 0;i< 32 ;i++){
int a1 = a & 1;
int b1 = b & 1;
int val = 0 ;
if(a1 == 0 && b1 == 0 && carry == 0){
val = 0;
carry = 0;
}else if(a1 == 1 && b1 == 1 && carry == 1){
val = 1;
carry = 1;
}else if(a1==0 && b1 ==0 || a1 ==0 && carry ==0 || b1 ==0 && carry ==0){
val = 1;
carry = 0;
}else{
val = 0;
carry = 1;
}
val = val << i;
sum = sum | val;
a = a >> 1;
b = b >> 1;
}
return sum;
}
};
总耗时: 660 ms
Python程序:
class Solution:
"""
@param a: The first integer
@param b: The second integer
@return: The sum of a and b
"""
def aplusb(self, a, b):
# write your code here, try to do it without arithmetic operators.
sum = 0
carry = 0
for i in range(32):
a1 = a & 1
b1 = b & 1
val = 0
if a1== 0 and b1 ==0 and carry ==0:
val =0
carry = 0
elif a1 == 1 and b1 == 1 and carry ==1:
val =1
carry =1
elif a1 == 0 and b1 ==0 or a1==0 and carry ==0 or b1 ==0 and carry ==0:
val = 1
carry = 0
else:
val = 0
carry = 1
val = val << i
sum = sum|val
a = a>>1
b = b>>1
return sum
总耗时: 203 ms
这样写还是很好理解的,在上面的博客链接中,还有另外一种方法,比较不好理解。
异或运算^ 与运算 & 加法运算<考虑进位> 加法运算<不考虑进位>
0 ^ 0 = 0 0 & 0 = 0 0 + 0 = 0 0 + 0 = 0
1 ^ 0 = 1 1 & 0 = 0 1 + 0 = 1 1 + 0 = 1
1 ^ 1 = 0 1 & 1 = 1 1 + 1 = 10 1 + 1 = 0
0 ^ 1 = 1 0 & 1 = 0 0 + 1 = 1 0 + 1 = 1
可以看出加法不考虑进位的情况下和异或运算结果是一样的。
与运算结果是1时候,表示要进位 1.为了更好的计算,左移一位,这个就是要进位的,进位的在和上面的结果相加,出现了递归的现象了。
sum = a ^ b
carry= a&b
a = sum
b = carry
递归下去。。。 a b中有0的时候结束
OK
Java程序:
class Solution {
/*
* param a: The first integer
* param b: The second integer
* return: The sum of a and b
*/
public int aplusb(int a, int b) {
// write your code here, try to do it without arithmetic operators.
if(b==0)
return a;
return aplusb( a ^ b,(a&b)<<1);
}
};
总耗时: 586 ms
非递归程序:
class Solution {
/*
* param a: The first integer
* param b: The second integer
* return: The sum of a and b
*/
public int aplusb(int a, int b) {
// write your code here, try to do it without arithmetic operators.
if(b==0)
return a;
while(b!=0){
int sum = a ^ b;
int carry = (a&b)<<1 ;
a = sum;
b = carry;
}
return a;
}
};
总耗时: 592 ms
上面中b后来被考虑成进位项,当所有位都没有进位时候也就是b ==0 的时候结束程序。
注意在递归程序中:不应该增加a==0的时候结束程序,可能出现a =0但是会进位的情况。
上面程序无论是递归还是非递归都是出现时间超时的问题。
class Solution:
"""
@param a: The first integer
@param b: The second integer
@return: The sum of a and b
"""
def aplusb(self, a, b):
# write your code here, try to do it without arithmetic operators.
if b == 0:
return a
if a == 0:
return b
while b!=0:
carry = (a&b)<<1
a = a ^ b
b = carry
return a
都是这个数据的问题
lintcode 中等题:A + B Problem A + B 问题的更多相关文章
- lintcode 中等题:partition array 数组划分
题目 数组划分 给出一个整数数组nums和一个整数k.划分数组(即移动数组nums中的元素),使得: 所有小于k的元素移到左边 所有大于等于k的元素移到右边 返回数组划分的位置,即数组中第一个位置i, ...
- lintcode 中等题:permutations II 重复数据的全排列
题目 带重复元素的排列 给出一个具有重复数字的列表,找出列表所有不同的排列. 样例 给出列表 [1,2,2],不同的排列有: [ [1,2,2], [2,1,2], [2,2,1] ] 挑战 使用递归 ...
- lintcode 中等题:permutations 全排列
题目 全排列 给定一个数字列表,返回其所有可能的排列. 您在真实的面试中是否遇到过这个题? Yes 样例 给出一个列表[1,2,3],其全排列为: [ [1,2,3], [1,3,2], [2,1,3 ...
- lintcode 中等题: Implement Trie
题目 Implement Trie Implement a trie with insert, search, and startsWith methods. 样例 注意 You may assu ...
- lintcode 中等题:majority number III主元素III
题目 主元素 III 给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的1/k. 样例 ,返回 3 注意 数组中只有唯一的主元素 挑战 要求时间复杂度为O(n),空间复杂度为O( ...
- lintcode 中等题:N Queens II N皇后问题 II
题目: N皇后问题 II 根据n皇后问题,现在返回n皇后不同的解决方案的数量而不是具体的放置布局. 样例 比如n=4,存在2种解决方案 解题: 和上一题差不多,这里只是求数量,这个题目定义全局变量,递 ...
- lintcode 中等题:搜索旋转排序数组II
题目 搜索旋转排序数组 II 跟进“搜索旋转排序数组”,假如有重复元素又将如何? 是否会影响运行时间复杂度? 如何影响? 为何会影响? 写出一个函数判断给定的目标值是否出现在数组中. 样例 给出[3, ...
- lintcode 中等题: reverse linked list II 翻转链表II
题目 翻转链表 II 翻转链表中第m个节点到第n个节点的部分 样例 给出链表1->2->3->4->5->null, m = 2 和n = 4,返回1->4-> ...
- lintcode 中等题:minimum window substring 最小子串覆盖
题目 最小子串覆盖 给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串. 样例 给出source = "ADOBECODEBANC ...
随机推荐
- ASP.NET MVC 及 Areas 简单控制路由
ASP.NET MVC中怎么去控制路由,这个想关的文章很多,我在这里就是自我总结一下,仅供参考. 1.我们新建一个项目,查看RouteConfig.cs,代码如下: public static voi ...
- 51nod1269 B君的圆锥
1629 B君的圆锥 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 B君要用一个表面积为S的圆锥将白山云包起来. B君希望包住的白山云体积尽量 ...
- php操作mysql数据库的基本类
代码如下 复制代码 <?php$dbhost='localhost';$dbuser='root';$dbpass='123456';$dbname='products';$connect=my ...
- JavaScript中使用console调试程序的坑
上DEMO a = {key1: [1, 2], 'key2': {'key4': '11'}, 'key3': [1, 2]} console.info(1,a) a.key2.key4 = '22 ...
- swift UIAlertController教程
在iOS8中,UIAlertView与UIActionSheet都已经退休,取而代之的是UIAlertController!它的使用示范如下://弹出一个警告框,标题是“提示”,信息是“我的博客:oa ...
- 键盘样式风格有关设置-iOS开发
一.键盘风格 UIKit框架支持8种风格键盘. typedef enum { UIKeyboardTypeDefault, // 默认键盘:支持所有字符 UIKey ...
- ASP.NET 运行机制
原本今天打算继续写ASP.NET MVC第四天的.但是由于里面涉及到asp.net运行机制的原理,如果不分析一下这里,mvc想说清楚还是挺困难的.既然要提到asp.net运行机制,所以打算还是说详细一 ...
- oracle中事务处理
事务用于保证数据的一致性,它由一组相关的dml语句组成,该组的dml语句要么全部成功,要么全部失败. 事务和锁 当执行事务操作时(dml语句),oracle会在被作用的表上加锁,防止其它用户改表的结构 ...
- 《Power》读书笔记
原创作品 版权所有 转载请注明出处! 序言 权力是“争”来的,不是“等”来的. 会计.工商管理.营销和销售部门.财务人员(背景).企业咨询小组 在位晋升而竞争的时候,对于公平竞争原则,有些人会采取变通 ...
- java集合类(三)About Iterator & Vector(Stack)
接上篇:java集合类学习(二) Talk about “Iterator”: 任何容器类,在插入元素后,还需要取回元素,因为这是容器的最基本工作.对于一般的容器,插入有add()相关方法(List, ...