| 排名 | 题号 | 题目名称 | 难度 | 频度 | 链接 |
|---|---|---|---|---|---|
| 3 | 415 | 字符串相加 | 容易 | 222 | LeetCode |
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。
你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。
示例 1:
输入:num1 = "11", num2 = "123"
输出:"134"
示例 2:
输入:num1 = "456", num2 = "77"
输出:"533"
示例 3:
输入:num1 = "0", num2 = "0"
输出:"0"
提示:
1 <= num1.length, num2.length <= 104num1和num2都只包含数字0-9num1和num2都不包含任何前导零
python
def addStrings(num1: str, num2: str) -> str:
"""
字符串相加 - 力扣415题
给定两个字符串形式的非负整数 num1 和 num2,
返回它们的和的字符串形式。
不能使用任何内置的BigInteger库或直接将输入转换为整数。
算法思路:模拟手工竖式加法,从最低位开始逐位相加
"""
# i 和 j 分别指向 num1 和 num2 的末尾(从个位开始)
i, j = len(num1) - 1, len(num2) - 1
# carry 表示进位,初始为0
carry = 0
# result 用于存储每一位的结果
result = []
# 只要还有数字没处理完,或者还有进位,就继续循环
while i >= 0 or j >= 0 or carry > 0:
# 获取当前位的数字,如果已经超出索引范围则为0
digit1 = int(num1[i]) if i >= 0 else 0
digit2 = int(num2[j]) if j >= 0 else 0
# 当前位相加:digit1 + digit2 + 进位
current_sum = digit1 + digit2 + carry
# 计算当前位的值(取模10)和新的进位(整除10)
result.append(str(current_sum % 10)) # 当前位数字
carry = current_sum // 10 # 进位
# 指针向前移动一位
i -= 1
j -= 1
# 因为我们是从个位开始添加的,所以需要反转结果
result.reverse()
# 将列表转换为字符串返回
return ''.join(result)
# ====== 测试用例 ======
if __name__ == "__main__":
# 测试用例1:常规情况
print(addStrings("11", "123")) # 输出: "134"
# 测试用例2:长度不同
print(addStrings("456", "77")) # 输出: "533"
# 测试用例3:带进位
print(addStrings("999", "1")) # 输出: "1000"
# 测试用例4:其中一个为0
print(addStrings("0", "0")) # 输出: "0"
详细解释
核心思想
这题就是模拟小学学的竖式加法,从个位(字符串末尾)开始,一位一位相加,处理好进位。
关键点
-
双指针法:用 i 和 j 两个指针分别指向两个字符串的末尾,同时向前遍历。
-
处理长度差异 :当一个字符串已经遍历完,另一个还有位数时,用
0补位。 -
进位处理:
- 当前位的和 = digit1 + digit2 + carry(上一次的进位)
- 当前位结果 = sum % 10
- 新的进位 = sum // 10
-
终止条件:只有当两个指针都超出范围且没有进位时才停止。
-
反转结果:因为我们是从低位开始添加的,所以最后需要反转列表。
复杂度分析
- 时间复杂度:O(max(m, n)),其中 m 和 n 是两个字符串的长度
- 空间复杂度:O(max(m, n)),存储结果