链表相加---链表OJ---两数之和

https://leetcode.cn/problems/add-two-numbers/?envType=study-plan-v2&envId=top-100-liked

链表相加---链表OJ---两数之和_第1张图片

        对于本题,可以选择用数组实现,那样比较简单;我们这里就用纯链表实现。

        纯链表实现有许多细节,比如链表长度不一样进位尾结点如果是0我们就要删除尾结点

        首先创建新链表

 //开辟新链表
    struct ListNode* head = (struct ListNode*)malloc(sizeof(struct ListNode));
    head->next = NULL, head->val = 0;
    //用tmp去将两个链表相加
    struct ListNode* tmp = head;

        由于需要考虑进位,我们这里想到的是,假想还有一个新链表,链表长度比l1和l2中长的链表再长一个结点,这个新链表全部初始化为0,用来记录进位

        这是假想,实质上是每次相加前,开辟一个新结点,用来记录进位,这个新结点就是tmp的next,每次计算完,tmp就变到tmp的next,即每一次的res = l1->val + l2->val + tmp->val;

        同时相加过程中要注意这两个链表是否走完,这里需要注意的是,两个链表可能同时走完。 

    while (l1 && l2) {
        struct ListNode* node =
            (struct ListNode*)malloc(sizeof(struct ListNode)); // node结点
        node->val = 0, node->next = NULL;                      //初始化为0
        tmp->next = node;
        int res = l1->val + l2->val + tmp->val; // res
        if (res >= 10) {                        // res>=10,就有进位
            tmp->val = res % 10;                //更新tmp的值
            node->val += 1;                     //进位
        } else {
            tmp->val = res;
        }
        tmp = tmp->next;
        l1 = l1->next;
        l2 = l2->next;
    }

        由于我们上面node->val都初始化为0,如果最后没有进位的话,那最后tmp走到尾结点时,该结点的位置val为0,我们需要删除这个0。就是一个尾删

if (tmp->val == 0) {
            struct ListNode* tail = head;
            while (tail->next->next) {
                tail = tail->next;
            }
            free(tail->next);
            tail->next = NULL;
        }

        最后,我们再将三种情况一一列出即可:l1和l2同时为空只有l1为空只有l2为空

        同时为空:

if (l1 == NULL && l2 == NULL) {
        if (tmp->val == 0) { //删除最后一个为0的结点
            struct ListNode* tail = head;
            while (tail->next->next) {
                tail = tail->next;
            }
            free(tail->next);
            tail->next = NULL;
        }
        return head;
    }

        l1为空:就只对l2进行“加法”:

if (l1 == NULL) {
        while (l2) {
            struct ListNode* node =
                (struct ListNode*)malloc(sizeof(struct ListNode));
            node->val = 0, node->next = NULL;
            tmp->next = node;
            int res = l2->val + tmp->val;
            if (res >= 10) {
                tmp->val = res % 10;
                node->val += 1;
            } else {
                tmp->val = res;
            }
            tmp = tmp->next;
            l2 = l2->next;
        }
        if (tmp->val == 0) { //删除最后一个为0的结点
            struct ListNode* tail = head;
            while (tail->next->next) {
                tail = tail->next;
            }
            free(tail->next);
            tail->next = NULL;
        }
        return head;
    }

        l2为空:就只有l1进行“加法”:

if (l2 == NULL) {
        while (l1) {
            struct ListNode* node =
                (struct ListNode*)malloc(sizeof(struct ListNode));
            node->val = 0, node->next = NULL;
            tmp->next = node;
            int res = l1->val + tmp->val;
            if (res >= 10) {
                tmp->val = res % 10;
                node->val += 1;
            } else {
                tmp->val = res;
            }
            tmp = tmp->next;
            l1 = l1->next;
        }
        if (tmp->val == 0) { //删除最后一个为0的结点
            struct ListNode* tail = head;
            while (tail->next->next) {
                tail = tail->next;
            }
            free(tail->next);
            tail->next = NULL;
        }
        return head;
    }

        再附一张图:

链表相加---链表OJ---两数之和_第2张图片

         最后,整体代码如下:

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
    //开辟新链表
    struct ListNode* head = (struct ListNode*)malloc(sizeof(struct ListNode));
    head->next = NULL, head->val = 0;
    //用tmp去将两个链表相加
    struct ListNode* tmp = head;

    while (l1 && l2) {
        struct ListNode* node =
            (struct ListNode*)malloc(sizeof(struct ListNode)); // node结点
        node->val = 0, node->next = NULL;                      //初始化为0
        tmp->next = node;
        int res = l1->val + l2->val + tmp->val; // res
        if (res >= 10) {                        // res>=10,就有进位
            tmp->val = res % 10;                //更新tmp的值
            node->val += 1;                     //进位
        } else {
            tmp->val = res;
        }
        tmp = tmp->next;
        l1 = l1->next;
        l2 = l2->next;
    }
    if (l1 == NULL && l2 == NULL) {
        if (tmp->val == 0) { //删除最后一个为0的结点
            struct ListNode* tail = head;
            while (tail->next->next) {
                tail = tail->next;
            }
            free(tail->next);
            tail->next = NULL;
        }
        return head;
    }
    if (l1 == NULL) {
        while (l2) {
            struct ListNode* node =
                (struct ListNode*)malloc(sizeof(struct ListNode));
            node->val = 0, node->next = NULL;
            tmp->next = node;
            int res = l2->val + tmp->val;
            if (res >= 10) {
                tmp->val = res % 10;
                node->val += 1;
            } else {
                tmp->val = res;
            }
            tmp = tmp->next;
            l2 = l2->next;
        }
        if (tmp->val == 0) { //删除最后一个为0的结点
            struct ListNode* tail = head;
            while (tail->next->next) {
                tail = tail->next;
            }
            free(tail->next);
            tail->next = NULL;
        }
        return head;
    }
    if (l2 == NULL) {
        while (l1) {
            struct ListNode* node =
                (struct ListNode*)malloc(sizeof(struct ListNode));
            node->val = 0, node->next = NULL;
            tmp->next = node;
            int res = l1->val + tmp->val;
            if (res >= 10) {
                tmp->val = res % 10;
                node->val += 1;
            } else {
                tmp->val = res;
            }
            tmp = tmp->next;
            l1 = l1->next;
        }
        if (tmp->val == 0) { //删除最后一个为0的结点
            struct ListNode* tail = head;
            while (tail->next->next) {
                tail = tail->next;
            }
            free(tail->next);
            tail->next = NULL;
        }
        return head;
    }
    return NULL;
}

你可能感兴趣的:(链表OJ题,链表,数据结构)