类似于大数加的操作,保存进位,注意处理长度可能不同的问题还有最后一个结点的进位问题。
我们先辨析几个概念:
链表头:数据内容为第一个元素的结点。
头指针:指向头结点元素的指针。
头结点:数据内容无效,其指针是头指针。
一句话描述为:头指针是指向头结点的指针,头结点是指向链表头的结点。
由这道题我们可以体会到头结点链表操作带来的便捷性。
先是我写的代码,没有用头结点,最后如果没有进位的话,要删除最后一个结点。
class Solution {
public:
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
int carry = 0;
ListNode* ptr = new ListNode(0);
ListNode* tail = ptr;
ListNode* ex = NULL;
while(l1 != NULL || l2 != NULL){
int val1 = 0;
if(l1 != NULL){ //巧妙的解决了长度不同的问题
val1 = l1->val;
l1 = l1->next;
}
int val2 = 0;
if(l2 != NULL){
val2 = l2->val;
l2 = l2->next;
}
int tmp = val1 + val2 + carry;
ptr->val= tmp%10;
carry = tmp/10;
ptr->next=new ListNode(0);
ex=ptr;
ptr=ptr->next;
}
if(carry == 1){
ptr->val = 1;
}
else
{
ex->next=NULL;//删除这个值为0的无效的结点
delete ptr;
}
return tail;
}
};
然后是采用头结点的代码,很简洁。
class Solution {
public:
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
int carry = 0;
ListNode* tail = new ListNode(0);
ListNode* ptr = tail;
while(l1 != NULL || l2 != NULL){
int val1 = 0;
if(l1 != NULL){
val1 = l1->val;
l1 = l1->next;
}
int val2 = 0;
if(l2 != NULL){
val2 = l2->val;
l2 = l2->next;
}
int tmp = val1 + val2 + carry;
ptr->next = new ListNode(tmp % 10);
carry = tmp / 10;
ptr = ptr->next;
}
if(carry == 1){
ptr->next = new ListNode(1);
}
return tail->next; //注意返回的是头结点的后一个结点,才是有效数据
}
};