题目
第2题 两数相加
https://leetcode-cn.com/problems/add-two-numbers/
题解
本题不太难,但是涉及到比较基础的细节
基础知识点:
- 链表的判空:直接判当前节点是否为空即可,而不是判断下一位是否为空
if (p != null) <=> if § (对)
if (p->next != null) (错) - for循环遍历链表,记得把p = p->next放在括号里鸭,for (init(x); judge(x); change(x))我第一次居然只写了判断条件。如果只写判断条件在括号可以用while语法,然后把指针移动放在花括号里面 while(p1 || p2)
- 结果链表最好统一成带头结点的链表,方便之后处理。我第一次硬是在头结点写入导致结果多了一位0。
- 带头节点的链表记得最后删除头结点,从第二位返回:
ListNode* ptr_to_delete = l0;
l0 = l0->next;
delete ptr_to_delete;
return l0;
本题算法考点:
主要是考察链表的加法,使用模拟法即可。
巧妙点的思路如官方题解所言
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/add-two-numbers/solution/liang-shu-xiang-jia-by-leetcode-solution/
- 如果两个链表的长度不同,则可以认为长度短的链表的后面有若干个 00 。
- 此外,如果链表遍历结束后,有carry>0,还需要在答案链表的后面附加一个节点,节点的值为 carry。
附代码:
我的:
(以下保留编码过程中的注释,方便复盘自我提醒)
/**
* Definition for singly-linked list.
* 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* l0 = new ListNode();
ListNode* p0 = l0;
ListNode* p1 = l1;
ListNode* p2 = l2;
int re = 0;
for (;p1 != nullptr && p2 != nullptr;p0 = p0 -> next, p1 = p1->next, p2 = p2->next) {
p0->next = new ListNode((p1->val + p2->val + re) % 10);
// p0->val = (p1->val + p2->val + re) % 10;
re = (p1->val + p2->val + re) / 10;
// p0->next = new ListNode();
// p0 = p0 -> next;
// p1 = p1->next;
// p2 = p2->next;
}
for (;p1 != nullptr;p0 = p0 -> next,p1 = p1->next) {
p0->next = new ListNode((p1->val + re) % 10);
// p0->val = (p1->val + re) % 10;
re = (p1->val + re) / 10;
// p0->next = new ListNode();
// p0 = p0 -> next;
// p1 = p1->next;
}
for (;p2 != nullptr;p0 = p0->next,p2 = p2->next) {
p0->next = new ListNode((p2->val + re) % 10);
// p0->val = (p2->val + re) % 10;
re = (p2->val + re) / 10;
// p0->next = new ListNode();
// p0 = p0->next;
// p2 = p2->next;
}
if (re != 0) {
p0->next = new ListNode(re);
// p0->val = re;
}
ListNode* ptr_to_delete = l0;
l0 = l0->next;
delete ptr_to_delete;
return l0;
}
};
官方题解:
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *head = nullptr, *tail = nullptr;
int carry = 0;
while (l1 || l2) {
int n1 = l1 ? l1->val: 0;
int n2 = l2 ? l2->val: 0; // 巧妙的判断将较短的值设置为0
int sum = n1 + n2 + carry;
if (!head) {
head = tail = new ListNode(sum % 10); // 不带头结点需要单独处理
} else {
tail->next = new ListNode(sum % 10);
tail = tail->next;
}
carry = sum / 10;
if (l1) {
l1 = l1->next;
}
if (l2) {
l2 = l2->next;
}
}
if (carry > 0) {
tail->next = new ListNode(carry);
}
return head;
}
};
/*
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/add-two-numbers/solution/liang-shu-xiang-jia-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*/
其他优秀题解:
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* head=new ListNode(-1);//存放结果的链表
ListNode* h=head;//移动指针
int sum=0;//每个位的加和结果
bool carry=false;//进位标志
while(l1!=NULL||l2!=NULL)
{
sum=0;
if(l1!=NULL)
{
sum+=l1->val;
l1=l1->next;
}
if(l2!=NULL)
{
sum+=l2->val; // 巧妙的点在于先累加值,然后再填入节点,少了对长度的过程
l2=l2->next;
}
if(carry)
sum++;
h->next=new ListNode(sum%10);
h=h->next;
carry=sum>=10?true:false;
}
if(carry)
{
h->next=new ListNode(1);
}
return head->next; // 这里注意清除头结点
}
};
/*
作者:chenlele
链接:https://leetcode-cn.com/problems/add-two-numbers/solution/liang-shu-xiang-jia-by-gpe3dbjds1/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*/