先放自己的屎山:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* list_create()
{
struct ListNode* H;
H=(struct ListNode*)malloc(sizeof(struct ListNode));
if(H==NULL)
{
printf("list malloc failed\n");
return H;
}
//initialize
//memset(H,0,sizeof(linklist));
H->val=0;
H-> next = NULL;
return H;
}
int tail_insert(struct ListNode* L, int value) {
struct ListNode* p;
//struct ListNode* q;
if(L==NULL)
{
printf("tail insert H is NULL\n");
return -1;
}
if((p=(struct ListNode*)malloc(sizeof(struct ListNode)))==NULL)
{
printf("malloc failed\n");
return -1;
}
p->val=value;
p->next=NULL;
struct ListNode* q=L;
while(q->next!=NULL)
{
q=q->next;
}
//3 insert
q->next=p;
return 0;
}
int list_show(struct ListNode* L)
{
struct ListNode* p;
if (L == NULL) {
printf("L is null\n");
return -1;
}
if ((p = (struct ListNode*)malloc(sizeof(struct ListNode))) == NULL) {
printf("malloc failed\n");
return -1;
}
p=L;
while (p->next!=NULL)
{
printf("%d\t",p->next->val);
p=p->next;
}
puts("\n");
return 0;
}
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode* p; // p是L1上的,q是L2上的
struct ListNode* q;
struct ListNode* temp;
struct ListNode* result;
//l1=list_create();
//l2=list_create();
//result=list_create();
p=(struct ListNode*)malloc(sizeof(struct ListNode));
p->val=0;
p->next=NULL;
q=(struct ListNode*)malloc(sizeof(struct ListNode));
q->val=0;
q->next=NULL;
temp=(struct ListNode*)malloc(sizeof(struct ListNode));
temp->val=0;
temp->next=NULL;
result=(struct ListNode*)malloc(sizeof(struct ListNode));
result->val=0;
result->next=NULL;
int add=0;
p = l1;
q = l2;
temp = result;
while (p != NULL || q != NULL || add != 0) {
int x = (p != NULL) ? p->val : 0;
int y = (q != NULL) ? q->val : 0;
int sum = x + y + add;
printf("x:%d,y:%d,sum:%d\n",x,y,sum);
add = sum / 10;
tail_insert(temp, sum % 10);
if (p != NULL) {
p = p->next;
}
if (q != NULL) {
q = q->next;
}
}
list_show(result);
//temp->next=temp->next->next;
//list_show(result);
//return result;
// 返回去掉虚拟头节点后的结果链表
struct ListNode* res = result->next;
//free(result); // 释放虚拟头节点的内存
return res;
}
个人的想法:
1.struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2)函数用于执行两数相加,
int list_show(struct ListNode* L)函数用于显示链表;int tail_insert(struct ListNode* L, int value)用于在链表尾部插入新元素;struct ListNode* list_create()用于创建新链表。
2.p节点为L1链表上的移动节点,q为L2链表上的移动节点,add为进位标志,初始化为0,用p加上q加上add来计算新节点放入链表result中,如果两数之和超过10需要进位,即add=1,p和q分别往后挪动一位,继续执行上述操作,如果一个链表结束后,仅移动另一链表,并将新值通过insert函数加入新链表。
3.因为result链表第一位为0,从第二位才开始执行相加操作,所以最后需要把头节点去掉,得到res,res即为所求。
再来看看官方代码:
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode *head = NULL, *tail = NULL;
int carry = 0;
while (l1 || l2) {
int n1 = l1 ? l1->val : 0;
int n2 = l2 ? l2->val : 0;
int sum = n1 + n2 + carry;
if (!head) {
head = tail = malloc(sizeof(struct ListNode));
tail->val = sum % 10;
tail->next = NULL;
} else {
tail->next = malloc(sizeof(struct ListNode));
tail->next->val = sum % 10;
tail = tail->next;
tail->next = NULL;
}
carry = sum / 10;
if (l1) {
l1 = l1->next;
}
if (l2) {
l2 = l2->next;
}
}
if (carry > 0) {
tail->next = malloc(sizeof(struct ListNode));
tail->next->val = carry;
tail->next->next = NULL;
}
return head;
}
官方代码的思路:
- 遍历两个链表,取出每个节点的值
- 处理结果链表的第一个节点
- 处理后续节点,更新进位值
- 移动链表指针,处理最后的进位
- 返回结果链表
遇到的问题
1.执行LeetCode时,发现输出结果总是很奇怪,如下图所示:
经过一番折腾发现,每次申请新链表节点时,需要对参数进行初始化,如:
struct ListNode *head = NULL, *tail = NULL;
2.这里经常报错,经修改发现问题如1一样。
3.结论
1.记得申请内存,
2.记得更新头虚拟节点
3.主要有两个情况1.链表等长相加 2.链表不等长一个空了另一个怎么加