2.在不能确定新链表的开头是谁时,常常在堆上创建一个 prehead 并让它的 next 指向新链表的开头,这样就可以之后再决定 prehead 的 next 是谁,若没有则会丢失头节点的信息
class Solution{
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2){
ListNode *head = l1; // 能确定新链表的开头是 l1,故保存 l1 开始的值即可,若没有则会丢失头节点的信息
bool carrybit = false; // 进位标志
while(l1->next != nullptr && l2->next != nullptr){ // 虽然 l1 和 l2 的值可以是 nullptr,但当它们到达超尾 nullptr 时就会丢失它们 parent 节点的信息,即尾节点的信息,导致无法在尾节点后接上另一个链的子链或新创建的 next 节点
int a = l1->val;
int b = l2->val;
if(carrybit){
a++;
}
if(a + b >= 10){
carrybit = true;
l1->val = (a + b) % 10;
}
else{
l1->val = a + b;
carrybit = false;
}
l1 = l1->next;
l2 = l2->next;
} // 退出循环时 l1 和 l2 至少有一个已经是其链表的尾节点了
int a = l1->val; // 即基本重复循环中还应有一次的应做但没做的操作,不同是不让 l1 和 l2 更新成各自的 next 了,
int b = l2->val; // 因为这时它们中至少有一个已经是其链表的尾节点了,若让它们继续更新成各自的 next 即 nullptr 就会丢失尾节点信息,导致无法在尾节点后接上另一个链的子链或新创建的 next 节点
if(carrybit){
a++;
}
if(a + b >= 10){
carrybit = true;
l1->val = (a + b) % 10;
}
else{
l1->val = a + b;
carrybit = false;
}
l1->next = (l1->next == nullptr ? l2->next : l1->next); // 此时 l1 和 l2 至少有一个是其链表的尾节点,要做的是如果 l1 已经是其链表的尾节点了就把 l2 的从 next 开始的子链表接到 l1 的尾节点后面
while(carrybit && l1->next != nullptr){ // 从这里开始已经没有 l2 的事了,因为即使 l2 不是其链表的尾节点,它的从 next 开始的子链也已经接到 l1 的尾节点后了;这个循环的目的就是处理进位 carrybit
l1 = l1->next;
if(l1->val == 9){
l1->val = 0;
carrybit = true;
}
else{
l1->val++;
carrybit = false;
}
}
if(carrybit){
l1->next = new ListNode(1); // 要在堆上创建,即在尾节点后接上新创建的 next 节点;注意要指定 val 值,不然它是不确定的了
}
return head;
}
};
leetcode 2
最新推荐文章于 2024-05-01 19:10:24 发布