題扣面試題:面試題65. 不用加減乘除做加法
題目鏈接:https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/
題目要求:
寫一個函數,求兩個整數之和,要求在函數體內不得使用 “+”、“-”、“*”、“/” 四則運算符號。
示例 1:
輸入: a = 1, b = 1
輸出: 2
提示:
a, b 均可能是負數或 0
結果不會溢出 32 位整數
解題思路
看到這道題,你腦子裏是否有很多問號???
我能想到的有兩種方法:
1、用函數代替 運算符,其實就是取巧,沒有根本解決這個問題。
2、採用位運算操作
位運算
因爲不能使用加減乘除四則運算,所以只能想到使用二進制的位運算實現相加操作
二進制位運算中,異或操作: 1^1=0 0^0=0 1^0=1 0^1=1,可以模擬無進位的加操作;
與操作:1&1=1 0&1=0 1&0=0 0&0=0,可以模擬進位的情況,再將與後的值左移一位即等於進位值。 普通的十進制數相加過程是:
1) 各位相加,無進位和
2) 計算進位值
3) 無進位和加上進位值
使用位運算的二進制數的相加過程相同:
1) 兩個二進制數各位異或,得到無進位的和
2) 二進制數各位與再左移,計算進位
3) 無進位和與進位異或
重複上面操作,直到不再有進位,即進位爲0。
相關問題: 不使用新的變量,交換兩個變量的值。比如有兩個變量a、b,希望交換它們的值。有兩種不同的操作: 1.基於加減法 – a = a + b; b = a - b; a = a - b;
2.基於位運算 – a = a ^ b; b = a ^ b; a = a ^ b;
解法
java解法
class Solution {
public int add(int a, int b) {
int c = 0 ;
c = Math.addExact(a, b);
return c;
}
}
C++解法
class Solution {
public:
int add(int a, int b) {
if(b==0)
return a ;
return add(a^b, (unsigned int)(a&b)<<1);
}
};
C語言解法
// 解法一
int add(int a, int b){
return (b == 0) ? a : add(a ^ b, (((unsigned int)(a & b)) << 1));
}
// 解法二
int add(int a, int b) {
// 無進位和、進位值
int sum, carry;
while (b != 0) {
// 異或操作得無進位和
sum = a ^ b;
// 與操作後移位得進位值
carry = ((unsigned int) (a & b) << 1);
// 循環,直到進位爲0
a = sum;
b = carry;
}
return a;
}
Python解法
class Solution:
def add(self, a: int, b: int) -> int:
s = sum([a,b])
return s