题目:
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例 2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]
提示:
每个链表中的节点数在范围 [1, 100] 内
0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零
C代码:
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode *head = NULL, *tail = NULL;
int carry = 0;
while (l1 || l2) {
int n1 = l1 ? l1->val : 0;
int n2 = l2 ? l2->val : 0;
int sum = n1 + n2 + carry;
if (!head) {
head = tail = malloc(sizeof(struct ListNode));
tail->val = sum % 10;
tail->next = NULL;
} else {
tail->next = malloc(sizeof(struct ListNode));
tail->next->val = sum % 10;
tail = tail->next;
tail->next = NULL;
}
carry = sum / 10;
if (l1) {
l1 = l1->next;
}
if (l2) {
l2 = l2->next;
}
}
if (carry > 0) {
tail->next = malloc(sizeof(struct ListNode));
tail->next->val = carry;
tail->next->next = NULL;
}
return head;
}
解析:
- struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2):这是函数的声明,它接收两个参数l1和l2,这两个参数都是指向ListNode结构体的指针,表示要相加的两个链表。函数返回一个指向ListNode结构体的指针,表示相加后的结果链表。
- struct ListNode *head = NULL, *tail = NULL;:声明两个指针变量head和tail,它们都初始化为NULL。head将指向结果链表的头节点,而tail将用于在链表的末尾添加新节点。
- int carry = 0;:声明一个整数变量carry,用于存储进位值。初始值为0。
- while (l1 || l2):这是一个循环,只要l1或l2不为空(即还有数字没有相加),循环就会继续。
- int n1 = l1 ? l1->val : 0; 和 int n2 = l2 ? l2->val : 0;:这两行代码使用三元运算符来获取l1和l2的当前节点的值,如果当前节点为空,则取0。
- int sum = n1 + n2 + carry;:计算当前位的和,包括前一次迭代的进位carry。
- if (!head) { ... }:如果head仍然为NULL(即结果链表还没有创建头节点),则执行以下操作:
- 分配内存给一个新的ListNode,并将其赋值给head和tail。
- 设置新节点的值val为sum % 10(当前位的数字)。
- 设置新节点的next指针为NULL。
- else { ... }:如果结果链表已经有头节点了,则执行以下操作:
- 分配内存给一个新的ListNode,并将其链接到tail->next。
- 设置新节点的值val为sum % 10。
- 更新tail指针指向新的节点,并将其next指针设置为NULL。
- carry = sum / 10;:更新进位值carry为sum除以10的结果。
- if (l1) { l1 = l1->next; } 和 if (l2) { l2 = l2->next; }:如果l1或l2不为空,将它们分别移动到下一个节点。
- if (carry > 0) { ... }:在循环结束后,如果还有进位(carry大于0),则在结果链表的末尾添加一个新的节点,其值为carry。
- return head;:返回结果链表的头节点指针。
笔记:
链表结构:链表是一种常见的数据结构,用于存储一系列元素,这些元素在内存中可以不是连续的。在C语言中,链表通常通过结构体(struct)来实现。链表中的每个元素通常也是一个结构体,至少包含两个成员:
- 存储数据的成员,例如一个整数或其他类型的数据。
- 指向链表中下一个元素的指针。
示例:
typedef struct ListNode {
int val; // 存储数据的成员,这里是整型数据
struct ListNode *next; // 指向链表中下一个节点的指针
} ListNode;