力扣--两数相加

发布时间 2023-09-10 20:17:18作者: DawnTraveler

2. 两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 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]

提示:
每个链表中的节点数在范围 [1, 100] 内
0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零

我的代码

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
    int temp, count = 0;
    struct ListNode* p1 = l1, *p2 =l2,*prev = NULL;
    while(p1 && p2){
        temp = p1->val + p2->val + count;
        if (temp >=10) {count = 1; temp = temp -10;}
        else count = 0;
        p1->val = temp;
        prev = p1; // 保存前一个节点
        p1 = p1->next;
        p2 = p2->next;
    }

    if (!p1){
        prev->next = p2;
    }
 
    while(prev->next){
        prev = prev->next;
        temp = prev->val + count;
        if (temp >=10) {count = 1; temp = temp -10;}
        else count = 0;
        prev->val = temp;
    }

    if (count) {
        struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
        prev->next = node;
        node->next = NULL;
        node->val = 1;
    }

    return l1;
}

题解:

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
    struct ListNode *head = NULL, *tail = NULL;
    int carry = 0;
    while (l1 || l2) {
        int n1 = l1 ? l1->val : 0;
        int n2 = l2 ? l2->val : 0;
        int sum = n1 + n2 + carry;
        if (!head) {
            head = tail = malloc(sizeof(struct ListNode));
            tail->val = sum % 10;
            tail->next = NULL;
        } else {
            tail->next = malloc(sizeof(struct ListNode));
            tail->next->val = sum % 10;
            tail = tail->next;
            tail->next = NULL;
        }
        carry = sum / 10;
        if (l1) {
            l1 = l1->next;
        }
        if (l2) {
            l2 = l2->next;
        }
    }
    if (carry > 0) {
        tail->next = malloc(sizeof(struct ListNode));
        tail->next->val = carry;
        tail->next->next = NULL;
    }
    return head;
}

总结:

大致思路

1.选取一个变量记录进位

2.我这里直接利用了之前便有的链表l1,在他的基础上改值,第一次循环到一个链表结尾。然后进行一个判断,如果l1结束,将l2的剩余部分接上去,然后再改值;如果l1没有结束,就在l1的基础上继续改值,操作同前。(这里我出现了一个小错误,如果l1结束,这里p1指向的不是最后一个节点,而是NULL,就不能直接用p1来接上p2剩余部分,要设计一个prev存取链表l1的最后一个节点)

3.这一题最容易错的是没有考虑到最后一个节点还能进位的情况,这样就会多出一个节点,需要单独进行判断。

4.题解这里设置比较巧妙,他的循环结束是直到两个链表都到结尾处,使用一个三元运算符来判断加值,并且单独设立了一个链表来存储结果,并分别设置头指针和尾指针,将数据不断往上加,但也要注意到最后一个节点进位的情况。