Swift 解法详解:LeetCode 371《两整数之和》


文章目录

摘要

这道题看起来很奇怪:我们要计算两个整数的和,但题目规定 不能用 + 或 - 运算符 。听起来像是脑筋急转弯,其实这是一个很经典的"位运算"应用题。通过理解二进制的加法规则,我们完全可以用 位运算 来模拟加法过程。

这类题不仅能训练我们的思维,还能加深对二进制和位操作的理解。在底层开发、嵌入式开发甚至编译器优化里,这些技巧都非常实用。

描述

题目要求:

给你两个整数 a 和 b,不能用 + 或 - 运算符,返回它们的和。

示例 1

txt 复制代码
输入: a = 1, b = 2
输出: 3

示例 2

txt 复制代码
输入: a = 2, b = 3
输出: 5

提示

  • -1000 <= a, b <= 1000

题解答案

要模拟加法,首先回忆一下二进制的运算规则:

  • 不带进位的加法(相当于 XOR 异或):

    • 0 ^ 0 = 0
    • 1 ^ 0 = 1
    • 0 ^ 1 = 1
    • 1 ^ 1 = 0
  • 进位的部分(相当于 AND 与运算,再左移一位):

    • 只有当两位都是 1 时才产生进位。

因此:

  • 用 a ^ b 计算不带进位的和。
  • 用 (a & b) << 1 计算进位。
  • 然后不断迭代,把"和"和"进位"相加,直到进位为 0。

这就是用位运算模拟加法的核心思想。

题解代码分析

下面是 Swift 实现:

swift 复制代码
import Foundation

class Solution {
    func getSum(_ a: Int, _ b: Int) -> Int {
        var x = a
        var y = b
        
        while y != 0 {
            // 非进位和
            let sum = x ^ y
            // 进位
            let carry = (x & y) << 1
            // 更新 x 和 y
            x = sum
            y = carry
        }
        
        return x
    }
}

// MARK: - Demo 演示
let solution = Solution()
print(solution.getSum(1, 2)) // 输出: 3
print(solution.getSum(2, 3)) // 输出: 5
print(solution.getSum(-2, 3)) // 输出: 1

代码拆解

  1. 初始化变量

    • x 表示当前的和(不带进位)。
    • y 表示进位。
  2. 循环模拟加法

    • sum = x ^ y:这是当前两数的无进位和。
    • carry = (x & y) << 1:这是进位。
    • 更新 x = sum,y = carry,继续迭代。
  3. 终止条件

    • 当进位 y = 0 时,说明没有更多进位了,x 就是最终的答案。

示例测试及结果

运行 Demo 代码:

txt 复制代码
输入: (1, 2)
输出: 3

输入: (2, 3)
输出: 5

输入: (-2, 3)
输出: 1

结果完全符合预期。

这个方法不仅适用于正数,也适用于负数,因为 Swift 的 Int 本质上是补码存储,位运算同样适用。

时间复杂度

  • 每次循环至少会让进位左移一位,所以最多执行 O(32) 次(对于 32 位整数)。
  • 在 Swift 中 Int 是 64 位的,也就是最多执行 O(64) 次。
  • 复杂度可以认为是 O(1)。

空间复杂度

  • 只用了常量级的几个变量,空间复杂度是 O(1)。

总结

这道题的关键在于理解:

  • a ^ b 负责"加法不带进位"的部分。
  • (a & b) << 1 负责"进位"的部分。
  • 不断迭代直到进位为 0。

这个方法绕开了 + 和 -,用纯粹的位运算模拟了加法的过程。

在实际场景中,位运算往往出现在底层优化或者特殊硬件环境中。比如:

  • 处理器底层 ALU 的加法实现。
  • 高性能计算场景里的快速运算。
  • 特定场景下避免溢出的操作。

掌握这类思路,可以帮助我们更好地理解计算机是如何在底层执行算术运算的。

相关推荐
Cc.Y3 小时前
Java零基础入门:字符串深度掌握——从基础API到StringBuilder性能优化
java·开发语言·性能优化
java资料站7 小时前
十一、评估测试
开发语言·人工智能·python
左手の明天7 小时前
SLIP 协议封装与解析详解:原理、C 代码与实战案例
linux·c语言·开发语言·c++
海上小飞龙7 小时前
【KMP算法-下篇】同一道题:Java 库函数 2600 微秒,手写 KMP 16 微秒
java·开发语言·算法
朝朝辞暮i8 小时前
C++ 第 12 课:局部变量、作用域、变量生命周期
开发语言·c++·算法
狗凯之家源码网8 小时前
淘客口令落地页生成器 PHP 版深度评测
开发语言·php
画绛集美术8 小时前
本地化部署LLM用于美术史问答:一间美术教室的实践记录
开发语言·php
八解毒剂8 小时前
【计组】中央处理器CPU
java·开发语言·计算机组成原理
FakeOccupational9 小时前
【电路笔记 信号】DBPSK 波形查找表+脉冲成形(升余弦+根升余弦滤波)
开发语言·笔记
打工仔折腾 AI9 小时前
工业场景下时序库与实时计算一体化架构选型实践对比
java·开发语言·后端·python·性能优化·架构·ai agent 实战