两数相加-链表

题目描述:

个人题解:

        由于输入的两个链表都是逆序存储数字的位数的,因此两个链表中同一位置的数字可以直接相加。先同时遍历两个链表,逐位计算它们的和,并与当前位置的进位值相加。具体而言,如果当前两个链表处相应位置的数字为 n1,n2;进位值为 carry,则它们的和为 n1+n2+carry;其中,答案链表处相应位置的数字为 (n1+n2+carry)%10,而新的进位值为(n1+n2+carry​)/ 10。     

如果两个链表的长度不同,则可以认为长度短的链表的后面有若干个 0 。

此外,如果链表遍历结束后,有 carry>0,还需要在答案链表的后面附加一个节点,节点的值为carry。

代码实现:

struct ListNode* createListNode(int val) {
    struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
    node->val = val;
    node->next = NULL;
    return node;
}

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
    // 构造哑巴节点 dummy,最后返回 dummy.next, 以方便处理新链表的头节点。
    struct ListNode* dummy = createListNode(0);
    struct ListNode* node = dummy; // node 一直会变化(前进)
    int carrier = 0; // 进位

    // 只要有没走到头的链表或者进位不为 0 就一直前进。
    while (l1 != NULL || l2 != NULL || carrier != 0) {
        // 求和,考虑可能有链表走到头
        int sum = (l1 != NULL ? l1->val : 0) + (l2 != NULL ? l2->val : 0) + carrier;

        // 在尾部添加节点
        node->next = createListNode(sum % 10);
        node = node->next;
        
        // 更新进位,并向两个链表尾部前进
        carrier = sum / 10;
        if (l1 != NULL) l1 = l1->next;
        if (l2 != NULL) l2 = l2->next;
    }

    return dummy->next;
}

复杂度分析:

设链表 1 的长度为 m,链表 2 的长度为 n。

时间复杂度:O(max(m,n)),其中 m 和 n 分别为两个链表的长度。需要遍历两个链表的全部位置,而处理每个位置只需要 O(1) 的时间。

空间复杂度:O(1)。注意返回值不计入空间复杂度。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值