[C语言][LeetCode][2]Add Two Numbers

Problems:
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Example:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.

题目是给定两个链表,代表两个非负整数。整数上的数字逆序存储,每一个节点包括一个数字,使这两个整数相加,然后用链表返回。

思路:

  1. 实际上就是一个设计一个类似加法器的东西,用链表的数据结构来实现。

  2. 加法器的基本思路要了解,进位带着走。

  3. 需要考虑两个链表长度不一致的情况

    1. len<min(len1,len2),公共部分的加法
    2. 当遍历完短链表时,注意加法的加数减少一项
    3. 全都遍历之后,若有进位,最高位记得新开结点去存放

C语言代码:

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
    
    struct ListNode* tmp1;
    struct ListNode* tmp2;
    struct ListNode* tmp3; //链表结点索引
    struct ListNode* l3 = NULL;//一开始第三个链表为空,l3链表头指针
    int carry=0;
    if(l1==NULL||l2==NULL)//有链表为空的话直接返回
    {
        return (l1==NULL?l2:l1);
    }
    
    tmp1=l1; //索引
    tmp2=l2;
    tmp3=l3;
    while(tmp1!=NULL&&tmp2!=NULL)//处理公共部分
    {
        struct ListNode* newnode= (struct ListNode*)malloc(sizeof(struct ListNode));
        newnode->val = (tmp1->val + tmp2->val + carry)%10;
        newnode->next = NULL;
        carry = (tmp1->val + tmp2->val + carry)/10;
        
        if(l3==NULL)//如果开始链表为空,那么就填充值
        {
            l3 = tmp3 = newnode;
        }
        else//如果不空,直接将newnode接在后面
        {
            tmp3->next = newnode;
            tmp3 = tmp3->next;// tmp3始终指向链表末尾
        }
        tmp1 = tmp1->next;
        tmp2 = tmp2->next;
    }
    
    if(tmp1==NULL)//如果第一个链表遍历完了
    {
        while(tmp2!=NULL)
        {
            struct ListNode* newnode = (struct ListNode*)malloc(sizeof(struct ListNode));
            newnode->val = (carry + tmp2->val)%10;
            newnode->next = NULL;
            carry = (carry + tmp2->val)/10;
            tmp3->next = newnode;
            tmp3 = tmp3->next; // tmp3移到里l3链表末尾
            tmp2 = tmp2->next;
        }
        if(carry!=0) // 最高位还有进位
        {
            struct ListNode* newnode = (struct ListNode*)malloc(sizeof(struct ListNode));
            newnode->val = (carry)%10;
            newnode->next = NULL;
            tmp3->next = newnode;
            newnode->next = NULL;
        }
    }
    
    if(tmp2==NULL)//如果第一个链表遍历完了
    {
        while(tmp1!=NULL)
        {
            struct ListNode* newnode = (struct ListNode*)malloc(sizeof(struct ListNode));
            newnode->val = (carry + tmp1->val)%10;
            newnode->next = NULL;
            carry = (carry + tmp1->val)/10;
            tmp3->next = newnode;

            tmp3 = tmp3->next; // tmp3移到里l3链表末尾
            tmp1 = tmp1->next;
        }
        if(carry!=0) // 最高位还有进位
        {
            struct ListNode* newnode = (struct ListNode*)malloc(sizeof(struct ListNode));
            newnode->val = (carry)%10;
            newnode->next = NULL;
            tmp3->next = newnode;

        }
    }
    return l3;   
}

注意点

  • 如何新建结点?
  • 结构体指针变量和结构体变量对于成员的引用方式?( .->
  • 加法器设计,value = (carry + add1 + add2 )% 10; carry = (carry + add1 + add2 ) /10
  • 关于新建链表的问题:
  1. 新建链表的标准做法是新建头结点分配结点空间,置next为NULL,然后再用头插法尾插法来构建链表。但是做题目时候注意返回的指针是头结点后一个有值的结点
  2. 上面这种方法没有标准头结点,链表的第一个结点即有值,所以需要多加一个if判断该结点是否为开始结点。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章