剑指offer66_不用加减乘除做加法
不用加减乘除做加法
写一个函数,求两个整数之和,要求在函数体内不得使用 +、-、×、÷ 四则运算符号。
数据范围
输入和输出都在int
范围内。
样例
输入:num1 = 1 , num2 = 2输出:3
算法思路
这是一个不使用加减运算符实现整数加法的算法,利用了位运算来模拟加法过程。核心思想是将加法分解为:
- 无进位相加(通过异或运算
^
实现) - 计算进位(通过与运算
&
和左移<<
实现) - 循环直到进位为0
- 时间复杂度:
O(1)
因为整数位数固定(例如32位整数),最坏情况下循环次数由进位传递决定,最多循环32次。 - 空间复杂度:
O(1)
只使用了常数个临时变量,不随输入规模变化。
class Solution {
public:int add(int num1, int num2) {while (num2) { // 当进位不为0时继续循环int sum = num1 ^ num2; // 无进位相加结果(异或)int carry = (num1 & num2) << 1; // 计算进位(与运算后左移1位)num1 = sum; // 更新num1为无进位和num2 = carry; // 更新num2为进位值}return num1; // 当进位为0时,num1即为最终结果}
};
实例演示(以 5 + 7
为例)
步骤分解:
- 初始状态:
num1 = 5
(二进制0101
),
num2 = 7
(二进制0111
) - 第一次循环:
sum = 0101 ^ 0111 = 0010
(十进制2
)carry = (0101 & 0111) << 1 = 0101 << 1 = 1010
(十进制10
)- 更新:
num1 = 2
,num2 = 10
- 第二次循环:
sum = 0010 ^ 1010 = 1000
(十进制8
)carry = (0010 & 1010) << 1 = 0010 << 1 = 0100
(十进制4
)- 更新:
num1 = 8
,num2 = 4
- 第三次循环:
sum = 1000 ^ 0100 = 1100
(十进制12
)carry = (1000 & 0100) << 1 = 0000 << 1 = 0000
(十进制0
)- 更新:
num1 = 12
,num2 = 0
- 终止:
num2 = 0
,退出循环,返回num1 = 12
。
最终结果:
5 + 7 = 12
✅