题目描述
- 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照逆序 的方式存储的,并且每个节点只能存储一位数字。
- 请你将两个数相加,并以相同形式返回一个表示和的链表。
- 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
题目链接:
https://leetcode-cn.com/problems/add-two-numbers
示例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]
解题思路
初学数据结构,思路比较简单。
- 元素说明
- 创造两个两个指针p和q分别跟踪输入链表l1和l2。
- 创造指针s用于构造新的空间;创造指针r充当工具指针,用于结点的插入。
- 创造jflag用作进位标志位,需要进位时为1。
- 思路说明
- 将两数相加分成三种情况,分别是l1、l2长度相等(p!=NULL&&q!=NULL),l1长度短于l2(p== NULL&&q!=NULL),l1长度长于l2(p== NULL&&q!=NULL)三种情况,分别进行处理。
- 将链表l1作为相加链表,返回l1作输出值。
- 用尾插法延长链表长度。
代码分析
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
int jflag=0;//设置进位标志位
struct ListNode*p,*q,*s,*r;
p=l1,q=l2;
while(p!=NULL&&q!=NULL) //l1、l2长度相等
{
p->val=p->val+q->val+jflag;
jflag=0; //进位标志位清零
if(p->val>9)//判断是否进位
{
p->val=p->val%10;
jflag=1;
}
p=p->next;q=q->next;
}
while(p!=NULL&&q==NULL)//l1长于l2
{
p->val=p->val+jflag;
jflag=0; //进位标志位清零
if(p->val>9)//判断是否进位
{
p->val=p->val%10;
jflag=1;
}
p=p->next;
}
while(p==NULL&&q!=NULL)//l2长于l1
{
r=l1;
while(r->next!=NULL)
r=r->next; //找到链表l1的末位
s=(struct ListNode*)malloc(sizeof(struct ListNode));//申请新的结点空间
s->next=NULL;//放空
r->next=s;//将r指向该空间
r=r->next;//r推进一位
p=r;//将p指向r
p->val=q->val+jflag;
jflag=0; //进位标志位清零
if(p->val>9)//判断是否进位
{
p->val=p->val%10;
jflag=1;
}
p=p->next;q=q->next;
}
if(p==NULL&&jflag==1) //链表末尾进位
{
r=l1;
while(r->next!=NULL)
r=r->next;
s=(struct ListNode*)malloc(sizeof(struct ListNode));//申请新结点
s->val=jflag;//将进位放入新结点空间
s->next=NULL;
r->next=s;
r=r->next;
p=r;
}
return l1;
}
- 长度相同时,把对应的元素相加即可。
- l1长于l2时,由于l1是主链表,相加时可以忽略l2空部分,后续推进时q也不用推进l2列表。
- l2长于l1时,l1需要不断地从链表的末尾延长,保证p和l2的指针q能够同步推进。
- 某些情况下会出现溢出,需要延长一位l1的末尾把溢出的jflag加上。
一个尾插入的图解备忘录
运行结果
还行,起码内存用的不多,转码人单片机程序写习惯了。
接下来好好学习算法,争取早日把时间也省下来。