给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
提示:
- 每个链表中的节点数在范围
[1, 100]
内 0 <= Node.val <= 9
- 题目数据保证列表表示的数字不含前导零
题目描述:
给定两个非空链表 l1
和 l2
,分别表示两个非负整数。链表中的每个节点都是一位数字。这两个数按照逆序方式存储,即个位排在链表首部。求它们的和,并以相同形式返回一个表示和的链表。
思路分析:
可以使用头插法和按位相加的方法,即从低位到高位逐位相加,若相加和大于等于10,进位1。最后处理进位即可得到最终结果。
算法流程:
-
定义一个进位变量 carry 和一个结果链表 curNode,并初始化它们的值为0。
-
循环遍历 l1 和 l2。如果其中有一个链表不为空,则继续相加,否则停止相加。
-
每次循环将 l1 和 l2 的对应节点的值相加,结果加上进位值 carry,将进位变量 carry 和相加结果之和的个位数设置给新结点 curNode,然后向 curNode 和 l1/l2 指向的结点移动。
-
循环结束之后,如果存在进位变量 carry,则需将该进位添加到新链表的尾部。
-
返回结果链表。
C语言代码实现:
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
// 定义一个进位变量和结果链表,并初始化
int carry = 0;
struct ListNode* curNode = (struct ListNode*)malloc(sizeof(struct ListNode));
curNode->next = NULL;
// 循环遍历两个链表,相加对应位置的节点
while (l1 || l2 || carry) {
int sum = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry;
carry = sum / 10;
struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));
newNode->val = sum % 10;
newNode->next = curNode->next;
curNode->next = newNode;
l1 = l1 ? l1->next : l1;
l2 = l2 ? l2->next : l2;
}
return curNode->next;
}
时间复杂度:O(max(m, n)),其中 m 和 n 分别是两个链表的长度。
空间复杂度:O(max(m, n)),即存放结果链表的空间。