LeetCode-2、两数相加

花时间写了个非常粗糙的链表求和(和上课时说的链表声明不太一样),因为错误还在最后补了一个功能,可以说是非常简陋了。anyway,还是做出来了,上题:

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:用C语言链表做,申请新链表l3,l1、l2两链表在到达较短的那个链表末尾前,9以内求和,逢10记录一个进位(flag=1的情况),加到下一个位数中,最后将较长的链表后面几位全部“赶入”l3中。
注意事项:
1、这里的链表定义和课堂学过的不太一样,它是用

struct ListNode {
     int val;
     struct ListNode *next;
}

定义的,而课堂上有一个封装过的头节点,所以在这里我们将第一个ListNode作为头节点,在最后返回时用

struct ListNode *k = l3;
l3=l3->next;
free(k);

抹去头节点(其实free无所谓,但是为了节省空间还是free下,养成好习惯)。
2、考虑特殊情况,如99999+999这种情况下,尾部多出来一个节点(值为1),于是需要开辟新节点,让进位能储存,代码如下:


//题目给的结构体声明
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

//解题区
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
//代码放置在此

    //声明链表,此后返回也是该值
    struct ListNode *l3 = (struct ListNode *)malloc(sizeof(struct ListNode)); 
    struct ListNode *p = l3;//需要注意的是,我们保留l3的头地址,用新定义的p指针作为“狗腿子”来进行操作

    //进制储存,存在进位时该值为1
    int flag = 0;

    //考虑长度相等的节点加法
    while(l1 != NULL && l2 != NULL)
    {
        //开辟新节点
        struct ListNode *newnode = (struct ListNode *)malloc(sizeof(struct ListNode));

        //先前没有进位的操作
        if(flag == 0)
        {
            newnode->val = l1->val + l2->val;
        }

        //先前前存在进位的操作
        else
        {
            newnode->val = l1->val + l2->val + 1;
            flag = 0;
        }

        //判断目前是否存在进位
        if(newnode->val >= 10)
        {
            newnode->val -= 10;
            flag = 1;
        }

        //尾插法
        p->next = newnode;
        l1 = l1->next;
        l2 = l2->next;
        p = p->next;
    }

    //赶入剩余数据(仍然要考虑进位)

    //l1长度大于l2时情况
    while(l1)
    {
        struct ListNode *newnode = (struct ListNode *)malloc(sizeof(struct ListNode));
        
        if(flag == 1)
        {
            newnode->val = l1->val + 1;
            flag = 0;
        }
        else
        {
            newnode->val = l1->val;
        }
        if(newnode->val >= 10)
        {
            newnode->val -= 10;
            flag = 1;
        }
        p->next = newnode;
        p = p->next;
        l1 = l1->next;
    }
    
    //l2长度大于l1时情况
    while(l2)
    {
        struct ListNode *newnode = (struct ListNode *)malloc(sizeof(struct ListNode));
        if(flag == 1)
        {
            newnode->val = l2->val + 1;
            flag = 0;
        }
        else
        {
            newnode->val = l2->val;
        }
        if(newnode->val >= 10)
        {
            newnode->val -= 10;
            flag = 1;
        }
        p->next = newnode;
        p = p->next;
        l2 = l2->next;
    }

    //最后存在进位情况的补充
    if(flag == 1)
    {
        struct ListNode *newnode = (struct ListNode *)malloc(sizeof(struct ListNode));
        newnode->val = 1;
        p->next = newnode;
        p = p->next;
    }

    //消除头节点与返回链表
    p->next = NULL;
    struct ListNode *k = l3;
    l3 = l3->next;
    free(k);
    return l3;
}
posted @ 2020-10-24 23:16  Desc_End  阅读(58)  评论(2)    收藏  举报