赞
踩
一、题目
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 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;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。