以下文章来源于负雪明烛 ,作者负雪明烛
1000 篇算法题解的作者,国内互联网大厂程序员,技术分享爱好者。 爱好算法题解写作,擅长深入浅出讲解计算机知识,乐于分享大厂见闻。和读者一起刷算法题,拿 Offer,交朋友!
出品 | 负雪明烛 (ID:fuxuemingzhu_writing)
加法是我们上小学的时候开始学习的第一种数学运算。
在算法题中,「求加法」问题大多考察「列竖式」求和。
题目中,「两数之和」通常与其他形式表示的数字结合起来:
做法都是非常类似的,本质是在考察各种数据表示形式:字符串,链表,数组,二进制。
我们只要掌握了用「列竖式」求「两数之和」的方法,这类题目全都可以秒杀。
我们先回顾一下十进制加法的计算过程:
使用「竖式」计算十进制的加法的方式:
int 型数字再求和,因为可能溢出;carry 不为 0,那么最后需要计算进位。以 415. 字符串相加 为例。
给定两个字符串形式的非负整数
num1和num2,计算它们的和并同样以字符串形式返回。你不能使用任何内建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。
示例 1:
输入:num1 = "11", num2 = "123"
输出:"134"
题目要我们求两个字符串形式表示的数字相加,按照「列竖式」的方法进行求解即可。
while (p1 >= 0 || p2 >= 0 || carry != 0)含义:num1 和 num2 只要有一个没遍历完,那么就继续遍历;num1 和 num2 都遍历完了,但是最后留下的进位 carry != 0,那么需要把进位也保留到结果中。digit 的时候,如果字符串 num1 和 num2 中有一个已经遍历完了(即 或者 ),则认为 num1 和 num2 的对应位置是 。该代码可以作为「求加法」的模板。
Java 代码如下:
class Solution {
public String addStrings(String num1, String num2) {
StringBuilder res = new StringBuilder(); // 返回结果
int p1 = num1.length() - 1; // 标记遍历到 num1 的位置
int p2 = num2.length() - 1; // 标记遍历到 num2 的位置
int carry = 0; // 进位
while (p1 >= 0 || p2 >= 0 || carry != 0) { // num1 没遍历完,或 num2 没遍历完,或进位不为 0
int digit1 = p1 >= 0 ? num1.charAt(p1) - '0' : 0; // 当前 num1 的取值
int digit2 = p2 >= 0 ? num2.charAt(p2) - '0' : 0; // 当前 num2 的取值
int add = digit1 + digit2 + carry; // 当前位置相加的结果
carry = add >= 10 ? 1 : 0; // 是否有进位
add = add >= 10 ? add - 10 : add; // 去除进位后留下的数字
res.append(add); // 把去除进位后留下的数字拼接到结果中
p1 --; // 遍历到 num1 的位置向左移动
p2 --; // 遍历到 num2 的位置向左移动
}
return res.reverse().toString(); // 把结果反转并返回
}
}
num1 和 num2 的长度;以 2. 两数相加 为例。
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
image-20211028084256433 示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807
本题中的两个链表表示的数字是个位在前,高位在后。
所以,我们可以从两个链表的开头开始同时向后遍历,模拟「列竖式」求加法的过程。
Java 代码如下:
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
int carry = 0;
while (l1 != null || l2 != null || carry != 0) {
int i1 = l1 != null ? l1.val : 0;
int i2 = l2 != null ? l2.val : 0;
int add = i1 + i2 + carry;
carry = add >= 10 ? 1 : 0;
add = add >= 10 ? add - 10 : add;
cur.next = new ListNode(add);
cur = cur.next;
if (l1 != null)
l1 = l1.next;
if (l2 != null)
l2 = l2.next;
}
return dummy.next;
}
}
a 和 b 的长度;看完本文,你可以解决以下题目:
while循环结束条件;参考:
推荐阅读:
每日打卡赢积分兑换书籍入口