题目:
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 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]
实现思路:
-
首先创建一个新的ListNode,用来存储相加后的结果。同时创建三个指针p1、p2、p3,分别指向两个输入链表和新链表的头节点。
-
对于链表中每个节点的相加操作,使用while循环实现,其中只要两个链表都不为空,就进行循环。每次循环中,将当前节点对应的值相加,并加上前一个节点相加的进位值carry。
-
如果相加的结果小于10,则直接将结果存入新链表中,并将p3指向下一个节点。否则,将相加结果减去10,进位值carry加1,然后将结果存入新链表中,并将p3指向下一个节点。
-
当其中一个链表为空时,继续循环处理另一个链表中的节点,直到整个链表都被处理完。
-
如果两个链表都为空,并且还有进位值carry,则创建一个新节点存储进位值,并将该节点添加到新链表的末尾。
-
最后返回新链表的头节点的下一个节点,因为新链表的头节点是用来初始化的,不存储任何有效的值。
总之,这段代码实现了两个链表的相加操作,采用了简单的逐位相加的思路,逐步计算每一位的进位和结果,并将结果存入一个新的链表中。
// 链表节点的定义
struct ListNode {
int val; // 节点的值
ListNode *next; // 指向下一个节点的指针
// 三个构造函数,用于初始化节点
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* ans=new ListNode(0); // 创建一个新链表,用于存储结果
ListNode* p1=l1; // 指针 p1 指向链表 l1 的头结点
ListNode* p2=l2; // 指针 p2 指向链表 l2 的头结点
ListNode* p3=ans; // 指针 p3 指向链表 ans 的头结点
int sum,carry=0; // sum 用于存储两个节点的值的和,carry 用于存储进位
// 对两个链表同时进行遍历
while(p1&&p2){
sum=p1->val+p2->val+carry; // 计算节点值的和
p1=p1->next; // 将指针 p1 向后移动一个节点
p2=p2->next; // 将指针 p2 向后移动一个节点
carry=0; // 将进位清零
if(sum<10){ // 如果节点值的和小于 10
ListNode* tem=new ListNode(sum); // 创建一个新节点
p3->next=tem; // 将新节点插入到 ans 链表的末尾
p3=p3->next; // 将指针 p3 向后移动一个节点
}
else { // 如果节点值的和大于等于 10
ListNode* tem=new ListNode(sum-10); // 创建一个新节点,节点值为 sum-10
carry++; // 进位加 1
p3->next=tem; // 将新节点插入到 ans 链表的末尾
p3=p3->next; // 将指针 p3 向后移动一个节点
}
}
// 如果链表 l1 还有剩余节点,继续遍历 l1
while(p1!=NULL){
ListNode* tem;
if(p1->val+carry<10){ // 如果节点值加上进位小于 10
tem=new ListNode(p1->val+carry); // 创建一个新节点,节点值为 p1->val+carry
carry=0; // 将进位清零
}
else{ // 如果节点值加上进位大于等于 10
tem=new ListNode(p1->val+carry-10); // 创建一个新节点,节点值为 p1->val+carry-10
carry=1; // 进位加 1
}
p3->next=tem; // 将新节点插入到 ans 链表的末尾
p3=p3->next; // 将指针 p3 向后移动一个节点
p1=p1->next; // 将指针 p1 向后移动一个节点
}
// 如果链表 l2 还有剩余节点,继续遍历 l2
while(p2!=NULL){
ListNode* tem;
if(p2->val+carry<10){ // 如果节点值加上进位小于 10
tem=new ListNode(p2->val+carry); // 创建一个新节点,节点值为 p2->val+carry
carry=0; // 将进位清零
}
else { // 如果节点值加上进位大于等于 10
tem=new ListNode(p2->val+carry-10); // 创建一个新节点,节点值为 p2->val+carry-10
carry=1; // 进位加 1
}
p3->next=tem; // 将新节点插入到 ans 链表的末尾
p3=p3->next; // 将指针 p3 向后移动一个节点
p2=p2->next; // 将指针 p2 向后移动一个节点
}
// 如果有进位,还需要在 ans 链表的末尾添加一个节点
if(p1==NULL&&p2==NULL&&carry==1){
ListNode* tem=new ListNode(1); // 创建一个新节点,节点值为 1
p3->next=tem; // 将新节点插入到 ans 链表的末尾
p3=p3->next; // 将指针 p3 向后移动一个节点
}
return ans->next; // 返回 ans 链表的第二个节点,因为第一个节点的值为 0
}
};