LeetCode 445.两数相加 II |刷题打卡

141 阅读2分钟

题目描述

给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。

你可以假设除了数字 0 之外,这两个数字都不会以零开头。

示例:

输入:(7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 8 -> 0 -> 7

思路

看似是链表题,本质上考察的是高精度加法。 高精度加法即位与位对齐进行运算,如个位与个位对齐,十位与十位对齐等。常见的模板题是计算用数组存储的数之间的和,这里不过是将用数组存储换成了用链表进行存储。

  • 思路1:翻转链表后求和进位再次翻转
  • 思路2:遍历两链表分别求和再求总和,创建新链表或沿用原有链表存储 思路2时间复杂度比较低,思路1空间复杂度比较低,翻转链表可以递归或者双指针,本题解使用思路1。

C++代码

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        if(!l1 && !l2)return NULL;
        if(l1 && !l2)return l1;
        if(!l1 && l2)return l2;
        int len1 = 0, len2 = 0;
        l1 = swapList(l1, len1), l2 = swapList(l2, len2);
        if(len1 < len2)swap(l1, l2);//如果l1比l2短交换两链表
        int t = 0, sum = 0; ListNode *p = l1, *q = l2, *pre;
        while(p && q){//p和q都未走到尽头
            sum = p->val + q->val + t;//求和
            p->val = sum % 10;//取余存储在l1上
            t = sum / 10;//t为进位值
            pre = p;//取p的前驱节点是为了防备出现p和q同时指向空但进位t>0的特殊情况
            p = p->next;
            q = q->next;
        }
        while(p){//q指向空p未指向空
            sum = p->val + t;
            p->val = sum % 10;
            t = sum / 10;
            pre = p;//防备p指向空t>0的特殊情况
            p = p->next;
        }
        if(t){
            ListNode *cur = new ListNode(t);
            pre->next = cur;
        }
        l1 = swapList(l1,len1);
        if(!l1->val && l1->next)l1 = l1->next;
        return l1;
    }
    ListNode* swapList(ListNode* l,int &len){//翻转链表的同时计算链表长度
        len ++ ;
        if(!l || !l->next)return l;
        ListNode *tail = swapList(l->next,len);
        l->next->next = l;
        l->next = NULL;
        return tail;
    }
};

本文正在参与「掘金 3 月闯关活动」,点击查看活动详情