LeetCode | Add Two Numbers(两个链表相加)

来源:互联网 发布:数据库管理系统教程 编辑:程序博客网 时间:2024/05/18 20:10


题目:

You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8


题意解析:

题目就是将两个链表对应位的数目进行相加,但如果超过十的话,需要进1,跟整数的加法一样,只是每个结点存储1位。


题目很简单,并且看到样例更会受到误导。需要先考察链表L1和链表L2的长度,哪一个比较长。当最后一位相加后再产生进位,也要单独处理。还有,我们建立链表的时候是在表头插入还是在表尾插入等等。这些方面都要考虑。


方案一:

这个是我的方法,将L2的数据加到L1上,当L2的长度比L1长的话,将多出的结点链接到L1上。(这里就导致一个问题,当我们最后销毁两个链表的时候,L2和L1有了公共结点,会导致系统崩溃。需要额外处理,不过我没有加上这段代码,只是设置q的父节点,当L2后续结点链接到L1后,将q的父节点的next指针设为空即可。)最末尾的时候,要单独处理一下进位。

#include <stdio.h>#include <stdlib.h>typedef struct LNode{    int data;    struct LNode *next;}LNode,*LinkList;LinkList InitList(void){    LinkList head = (LinkList)malloc(sizeof(LNode));    if(head == NULL){        printf("Memory allocation failure!\n");        exit(1);    }    head->next = NULL;    return head;}void CreateList(LinkList head,int data){    LinkList p = (LinkList)malloc(sizeof(LNode));    if(!p){        printf("Memory allocation failure!\n");        exit(1);    }    p->data = data;    p->next = head->next;    head->next = p;}void AddList(LinkList dest,LinkList src){    LinkList p,q,parent;    int carryover = 0;    if(!dest || !src){        printf("NULL!");        exit(1);    }    parent = dest;    p = parent->next;    q = src->next;    while(p && q){        p->data += q->data + carryover;        carryover = p->data / 10;        p->data %= 10;        parent = p;        p = parent->next;        q = q->next;    }    if(q)   // q->length > p->length        parent->next = q;    q = parent->next;   //将q->length > p->length统一到q->length < p->length上    while(carryover && q){  //如果进位存在,并且q不为空指针的时候,将carryover加到q->data上        q->data += carryover;        carryover = q->data / 10;        q->data %= 10;        parent = q;        q = q->next;    }    if(carryover){  //单独处理进位        LinkList Q = (LinkList)malloc(sizeof(LNode));        if(!Q)            exit(1);        Q->data = carryover;        Q->next = NULL;        parent->next = Q;    }}void PrintList(LinkList head){    LinkList p = head->next;    while(p){        printf("%d ",p->data);        p = p->next;    }    printf("\n");}void DestoryList(LinkList head){    LinkList p = head->next,q;    head->next = NULL;    while(p){        q = p->next;        free(p);        p = q;    }}int main(void){    int n,m,data;    LinkList dest,src;    dest = InitList();    src = InitList();    printf("input how many numbers of n and m:");    while(scanf("%d %d",&n,&m) == 2){        printf("input the n+m datas:");        for(int i = 0;i < n;++i){            scanf("%d",&data);            CreateList(dest,data);        }        for(int i = 0;i < m;++i){            scanf("%d",&data);            CreateList(src,data);        }        AddList(dest,src);        PrintList(dest);        printf("input how many numbers of n and m:");    }    return 0;}


方案二:

如果这个题目,创建第三方链表会更方便,并且将L1->data 、L2->data和carryover三个数相加,分两次进行,会简化思路,得到更好的效果。下面这段代码摘自网络,很值得学习!

struct ListNode {    int val;    ListNode *next;    ListNode(int x) : val(x), next(NULL) {}};class Solution {public:    ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {ListNode* ret = NULL;ListNode** cur = &ret;int carry = 0;int sum = 0;while(l1 != NULL || l2 != NULL){sum = carry;if(l1 != NULL){sum += l1->val;l1 = l1->next;}if(l2 != NULL){sum += l2->val;l2 = l2->next;}carry = sum/10;sum %= 10;*cur = new ListNode(sum);cur = &(*cur)->next;}        if(carry > 0)*cur = new ListNode(carry);return ret;    }};




0 0
原创粉丝点击