【LeetCode刷题】2. 两数相加

先放自己的屎山:

/**
 * 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. 遍历两个链表,取出每个节点的值
  2. 处理结果链表的第一个节点
  3. 处理后续节点,更新进位值
  4. 移动链表指针,处理最后的进位
  5. 返回结果链表

遇到的问题

1.执行LeetCode时,发现输出结果总是很奇怪,如下图所示:
请添加图片描述
经过一番折腾发现,每次申请新链表节点时,需要对参数进行初始化,如:

 struct ListNode *head = NULL, *tail = NULL;

2.这里经常报错,经修改发现问题如1一样。
请添加图片描述
请添加图片描述

3.结论

1.记得申请内存,
2.记得更新头虚拟节点
3.主要有两个情况1.链表等长相加 2.链表不等长一个空了另一个怎么加

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值