数据结构--链表系列 两个数相加

本文详细解析了如何使用链表表示非负整数并进行加法运算,通过正向遍历链表,逐位求和并处理进位,最终生成表示和的新链表。文章深入探讨了链表操作技巧,包括哨兵头结点的使用,以及如何处理不同长度链表的求和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、题目

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

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

二、分析

思路分析

1.每个链表的每个节点是一位数字,也就是取值在[0,9],由此可以知道两数之和最大进位为1

2.链表的每个节点组成的数字,是链表从尾到头组成的一个数字

3.求两个数的和是从低位到高位的,而链表的头部正好代表了数的低位,于是可以正向遍历链表,并且边遍历边求和

4.在求和过程中需要考虑进位,如果和小于10,则直接将节点添加到返回链表

5.如果和大于10,则需要对10取余作为节点的值,将进位计入下一次求和中

6.如果某一个链表先结束,如果c==0,直接将另一个链表挂到返回链表中

7.如果c!=0,则需要重复上述求和的过程

8.最后需要考虑,如果最高位求和后大于10,需要新增加一位,添加到链表上

9.上述思路是为了方便思考,在代码实现的时候可以优化,不需要分这么多情况,可以将两个链表的长度考虑成一样的,没有的话在做求和的时候补0.

三、代码

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        //分析:链表的头部表示数字的低位,求和的时候从低位到高位开始求和,因此直接从头部开始遍历两个链表
        //每一位的数字范围是0-9,和最大为18,当前的和进位最高位1
        // 直接相加两个节点的值,如果小于10,直接创建一个新的节点,开辟新的空间存放结果
        //如果和大于10,则对10求余,将余数的结果存放到新的节点空间,保存进位的值
        // 直到某一个链表结束,如果没有进位,直接将另外一个链表的剩余节点加到当前res
        //如果有进位,则将长链表的下一个节点加上进位,判断是否有进位,还有进位继续加,没有进位执行上一步

        //为了便于操作,给返回的链表加上一个哨兵头结点,返回直接返回该结点的next
        ListNode* res = new ListNode(-1);
        res->next = nullptr;
        ListNode* cur = res;//res需要一个遍历结点,加入结点之间的位置关系
        
        int c = 0;//表示进位
        while (l1 || l2) {
            //创建一个结点,用于存放结果值
            ListNode* node = new ListNode(-1);
            node->next = nullptr;
               
            //计算当前结点的值,需要加上进位
            //这里相当于是把两个链表考虑成节点数一样的,通过补0来实现
            int num1=l1?l1->val:0;
            int num2=l2?l2->val:0;
            int temp = num1 + num2 + c;
            node->val = temp % 10;//个位数
            c = temp / 10;//进位数
            cur->next = node;//定义了哨兵结点,所以可以统一直接next
            cur = cur->next;

            //最后将两个链表依次后移
            if(l1) l1 = l1->next;
            if(l2) l2 = l2->next;
        }

        if (c != 0) {
            ListNode* node = new ListNode(c);
            node->next = nullptr;
            cur->next = node;
        }
        return res->next;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值