力扣第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
  • 题目数据保证列表表示的数字不含前导零

【分析】

要求将链表进行逆序存储,然后将链表的每位数字进行相加,并且每个位置只能存储一个数字。

如果是正序的话满足原则:从右向左,对位相加,逢十进一的原则,那么对于本题逆序而言也是遵循的,只不过是从左向右,对位相加,逢十进一。最后的结果依然按照逆序输出。(也就是说,如果按照逆序进行相加,我们需要将最后的结果进行逆序。由于输入的两个链表都是逆序存储数字的位数的,因此两个链表中同一位置的数字可以直接相加,这样得到的结果最后就是逆序的。比如输入243和564,我们按照逆序加是807,最后要逆序输出708。如果我们直接对同一位置数字进行相加,2+5=7,4+6=10,向前进1,3+4+1=8,最后输出依然是708。)

先定义一个链表3,用来输出最后的结果。刚开始,l3指向空,然后定义一个移动指针p,刚开始指向l3。定义一个进位,初始值赋为0。

当两个链表均不为空的时候,首先定义一个节点num,用来表示l1+l2的值。在加的过程中,我们需要考虑前面两个数加的有没有进位,如果有需要进一起加入。因此,我们num可以表示为num->val=(l1->val+l2->val+jinwei)%10,对10去余是为了将进位去除,只留下一位数字(比如相加为11,那么num应该等于1,然后向前面进1位;比如相加为23,那么num应该等于3,然后向前面进2位),而对于每次加的进位,同意需要计算,可通过jinwei=(l1->val+l2->val+jinwei)/10,对10求商,商为进位。(比如相加为11,那么jinwei应该为1位;比如相加为23,那么jinwei应该为1位2)。求出num后,需要将p的后继指向num,然后将p指向p的后继。最后将l1和l2向后遍历重复上述工作。

当其他有一个链表为空的时候,不能直接加入到l3中,而是要考虑进位(可能两个链表中最后产生的和有进位),流程和两个链表均为空时一致,只不过去掉已经为空的链表即可。

最后需要考虑有没有剩下进位,如果进位不为零,需要将进位加入到l3中。并且返回l3的后续节点(也就是要求的结果)

具体案例分析1:

1 = [2,4,3], l2 = [5,6,4]

首先l3=p->NULL,num=7(2+5=7,取余后为7),jinwei=0(2+5=7,取商后为0);然后l3->7(此时p指向7)

l3->7(此时p指向7),num=0(6+4=10,取余后为0),jinwei=1(6+4=10,取商后为1);然后l3->7->0(此时p指向0)

l3->7->0(此时p指向0),num=8(3+4+1=8,取余后为8),jinwei=1(3+4+1=8,去商后为0);然后l3->7->0->8(此时p指向8)

具体案例分析2:

l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]

首先l3=p->NULL,num=8(9+9=18,取余后为8),jinwei=0(9+9=18,取商后为1);然后l3->8(此时p指向8)

l3->8(此时p指向8),num=9(9+9+1=19,取余后为9),jinwei=0(9+9+1=19,取商后为1);然后l3->8->9(此时p指向9)

l3->8->9(此时p指向9),num=9(9+9+1=19,取余后为9),jinwei=0(9+9+1=19,取商后为1);然后l3->8->9->9(此时p指向最后一个9)

l3->8->9->9(此时p指向最后一个9),num=9(9+9+1=19,取余后为9),jinwei=0(9+9+1=19,取商后为1);然后l3->8->9->9->9(此时p指向最后一个9)

l3->8->9->9->9(此时p指向最后一个9),此时链表2为空,只用看链表,num=0(9+1=10,取余后为0),jinwei=1(9+1=10,取商后为1);然后l3->8->9->9->9->0(此时p指向0)

l3->8->9->9->9->0(此时p指向最后一个9),此时链表2为空,只用看链表,num=0(9+1=10,取余后为0),jinwei=1(9+1=10,取商后为1);然后l3->8->9->9->9->0->0(此时p指向最后一个0)

l3->8->9->9->9->0->0(此时p指向最后一个0),此时链表2为空,只用看链表,num=0(9+1=10,取余后为0),jinwei=1(9+1=10,取商后为1);然后l3->8->9->9->9->0->0->0(此时p指向最后一个0)

3->8->9->9->9->0->0->0(此时p指向最后一个0)此时链表1和2均为空,但是进位剩下一个一,因此需要将进位加入。l3->8->9->9->9->0->0->0->1(此时p指向一个1)

最后返回l3->next=[8,9,9,9,0,0,0,1]

C语言具体代码如下:

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
	struct ListNode* l3=(struct ListNode*)malloc(sizeof(struct ListNode));
	l3->next=NULL;
	struct ListNode* p=l3;
	int jinwei=0;
	while(l1 != NULL && l2 != NULL){//从前往后进行相加
		struct ListNode *num=(struct ListNode*)malloc(sizeof(struct ListNode));
        num->next=NULL;
        num->val=(l1->val+l2->val+jinwei)%10;
        jinwei=(l1->val+l2->val+jinwei)/10;
        p->next=num;
        p=p->next;
        l1=l1->next;
        l2=l2->next;
	}
	while(l1 != NULL){ //链表2为空的时候,只剩下链表1 
		struct ListNode *num=(struct ListNode*)malloc(sizeof(struct ListNode));
        num->next=NULL;
        num->val=(l1->val+jinwei) % 10;
        jinwei=(l1->val+jinwei) / 10;
        p->next=num;
        p=p->next;
        l1=l1->next;
	}
	while(l2 != NULL){ //链表1为空的时候,只剩下链表2 
		struct ListNode *num=(struct ListNode*)malloc(sizeof(struct ListNode));
		num->next=NULL;
		num=(l2->val+jinwei) % 10;
		jinwei=(l2->val+jinwei) / 10;
		p->next=num;
		p=p->next;
		l2=l2->next;
	}
	if(jinwei != 0){//最后还剩下进位时
		struct ListNode *num=(struct ListNode*)malloc(sizeof(struct ListNode));
		num->next=NULL;
        num->val=jinwei;
        p->next=num;
	}
	return l3->next; 
}

时间复杂度O(max(m,n));空间复杂度 O(max(m,n))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值