leetcode腾讯精选练习之两数相加(一)

两数相加

题目:

给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

思路:

1.定义一个带头结点的链表同时定义一个指针指向该结点
2.定义两个指针分别指向两个链表的头结点
3.定义一个int的进位标志c
4.循环遍历两个链表对应结点的值相加然后和10取余获取当前结点的值,做除法运算获取是否需要近卫,结果链表采用尾插法保证顺序
5.遍历结束后,判断最后一位相加的结果是否有进位,如果进位标志大于0说明有进位在插入一个进位结点

代码:

第一版:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    ListNode res(-1);
    ListNode* p1 = l1;
    ListNode* p2 = l2;
    ListNode* pRes = &res;
    int c = 0;
    while (p1 != NULL || p2 != NULL)
    {
        int pA = p1 == NULL ? 0 : p1->val;
        int pB = p2 == NULL ? 0 : p2->val;
        int tmp = pA + pB + c;
        c = tmp / 10;
        pRes->next = new ListNode(tmp % 10);
        pRes = pRes->next;
        p1 = p1 == NULL ? NULL : p1->next;
        p2 = p2 == NULL ? NULL : p2->next;
    }
    if (c > 0)
    {
        pRes->next = new ListNode(c);
    }
    return res.next;
}

第二版:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    ListNode res(-1);
    ListNode* pRes = &res;
    int c = 0;
    while (l1 != NULL || l2 != NULL)
    {
        int pA = l1 == NULL ? 0 : l1->val;
        int pB = l2 == NULL ? 0 : l2->val;
        int tmp = pA + pB + c;
        c = tmp / 10;
        pRes->next = new ListNode(tmp % 10);
        pRes = pRes->next;
        l1 = l1 == NULL ? NULL : l1->next;
        l2 = l2 == NULL ? NULL : l2->next;
    }
    if (c > 0)
    {
        pRes->next = new ListNode(c);
    }
    return res.next;
} 

终版:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    ListNode res(-1);
    ListNode* pRes = &res;
    int c = 0;
    while (l1 != NULL || l2 != NULL)
    {
        int tmp = c;
        if (l1 !=NULL)
        {
            tmp += l1->val;
            l1 = l1->next;
        }
        if (l2 != NULL)
        {
            tmp += l2->val;
            l2 = l2->next;
        }

        c = tmp / 10;
        pRes->next = new ListNode(tmp % 10);
        pRes = pRes->next;
    }
    if (c > 0)
    {
        pRes->next = new ListNode(c);
    }
    return res.next;
}

总结:

1.第一版就是按照思路一步一步完成的。

2.第二版去掉了临时变量,直接遍历两个链表,以减少内存开销

3.终版是去掉了两次重复的判断,以减少时间开销

4.结果的存储采用尾插法

原文地址:https://www.cnblogs.com/zh20130424/p/12184865.html