给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
来源:力扣(LeetCode)https://leetcode-cn.com/problems/add-two-numbers
几个技巧
- 使用哑节点,作为起始head的前一个节点,方便返回
- 之前把carry作为条件语句进行判断,先判断是否要进位,如果要进位,先对结果进位,然后再看看结果是否需要进位,如果要进位,再做处理。而答案用 sum = x + y + sum. 就不需要那么多条件语句了。
- 把NULL节点当作0. 我一开始的想法是先分别遍历两个列表,直到一方为NULL。然后又开始分别写连个循环,处理剩下的部分。但是一旦把NULL当作0,就只要写一次循环了。
正确的思路可以让代码简洁,让逻辑不清,思路不对就会让代码又臭又长啊。
代码如下
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *createNode(int val){
struct ListNode *node;
node = (struct ListNode *)malloc(sizeof(struct ListNode));
node->val = val;
node->next = NULL;
return node;
}
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
//哑节点, 不存放任何数据, 用于获取头节点
struct ListNode *dummy = createNode(0);
struct ListNode *p = l1, *q = l2, *curr = dummy;
int x, y, sum, carry = 0;
//当两个节点都没有遍历结束时
while ( p != NULL || q != NULL ){
// 如果为空, 用0补全
x = ( p != NULL ) ? p->val : 0;
y = ( q != NULL ) ? q->val : 0;
//计算
sum = x + y + carry;
//创建新的节点存放数据
curr->next = createNode(sum % 10);
curr = curr->next;
carry = sum / 10;
if ( p != NULL ) p = p->next;
if ( q != NULL ) q = q->next;
}
if ( carry > 0 ){
curr->next = createNode(carry);
}
return dummy->next;
}