leetcoed 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

题目数据保证列表表示的数字不含前导零

C代码:

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. struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2):这是函数的声明,它接收两个参数l1l2,这两个参数都是指向ListNode结构体的指针,表示要相加的两个链表。函数返回一个指向ListNode结构体的指针,表示相加后的结果链表。
  2. struct ListNode *head = NULL, *tail = NULL;:声明两个指针变量head和tail,它们都初始化为NULL。head将指向结果链表的头节点,而tail将用于在链表的末尾添加新节点。
  3. int carry = 0;:声明一个整数变量carry,用于存储进位值。初始值为0。
  4. while (l1 || l2):这是一个循环,只要l1或l2不为空(即还有数字没有相加),循环就会继续。
  5. int n1 = l1 ? l1->val : 0; 和 int n2 = l2 ? l2->val : 0;:这两行代码使用三元运算符来获取l1和l2的当前节点的值,如果当前节点为空,则取0。
  6. int sum = n1 + n2 + carry;:计算当前位的和,包括前一次迭代的进位carry。
  7. if (!head) { ... }:如果head仍然为NULL(即结果链表还没有创建头节点),则执行以下操作:
    • 分配内存给一个新的ListNode,并将其赋值给head和tail。
    • 设置新节点的值val为sum % 10(当前位的数字)。
    • 设置新节点的next指针为NULL。
  8. else { ... }:如果结果链表已经有头节点了,则执行以下操作:
    • 分配内存给一个新的ListNode,并将其链接到tail->next。
    • 设置新节点的值val为sum % 10。
    • 更新tail指针指向新的节点,并将其next指针设置为NULL。
  9. carry = sum / 10;:更新进位值carry为sum除以10的结果。
  10. if (l1) { l1 = l1->next; } 和 if (l2) { l2 = l2->next; }:如果l1或l2不为空,将它们分别移动到下一个节点。
  11. if (carry > 0) { ... }:在循环结束后,如果还有进位(carry大于0),则在结果链表的末尾添加一个新的节点,其值为carry。
  12. return head;:返回结果链表的头节点指针。

笔记:

链表结构:链表是一种常见的数据结构,用于存储一系列元素,这些元素在内存中可以不是连续的。在C语言中,链表通常通过结构体(struct)来实现。链表中的每个元素通常也是一个结构体,至少包含两个成员:

  1. 存储数据的成员,例如一个整数或其他类型的数据。
  2. 指向链表中下一个元素的指针。

示例:

typedef struct ListNode {

    int val;      // 存储数据的成员,这里是整型数据

    struct ListNode *next; // 指向链表中下一个节点的指针

} ListNode;

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值