leetcode2--add two numbers(两数之和)

 原题链接

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

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

示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]

示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

提示:

  • 每个链表中的节点数在范围 [1, 100] 内
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零

一些解题碎碎念

最开始的想法是将两个链表给的信息转化为整数,再将两个整数相加,最后将和转化为一个链表。但是这种方法放到力扣上跑的话,经不住大数检验(大到不仅超过int范围还超过unsigned int的范围),因此有了下面所示代码。

思路为对应位相加,用flag数组存进位信息,ans数组存每个位处理后的数值,处理每个位包括两种情况:一个是低位进1该位加1,一个是该位要进位减10。处理完每个位后还要注意最高位的进位:如果最高位有进位的话是要产生一个新的最高位。

在力扣中,这道题结点数在【1,100】内,因此ans数组可设的比100大点。

最后想说的一点是对两个链表的处理,如果两个链表等长,那没啥好说的。但是这里要考虑一般情况,即链表不等长。先处理两个链表均不为空的部分,再处理剩下的部分。(可参照链表二路归并的思想)

//无需考虑溢出,采用对应位相加并进位
#include<iostream>
using namespace std;

struct ListNode {             //结点类型
    unsigned int val;
    ListNode* next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode* next) : val(x), next(next) {}
};
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        int flag[100] = { 0 };
    int i = 1;
    int ans[100] = { 0 };
    while (l1 != NULL && l2 != NULL)
    {
        int tmp = l1->val + l2->val;
        if (flag[i - 1])     //低一位有进位。该位加一
        {
            tmp++;
        }
        if (tmp >= 10)      //该位要进位,产生进位信息并减10
        {
            flag[i] = 1;
            tmp -= 10;
        }
        ans[i - 1] = tmp;
        i++;
        l1 = l1->next;
        l2 = l2->next;
    }       //最后有i-1个数
            //ans数组记录到下标位i-2
            //flag数组记录到下标为i-1
    while (l1 != NULL)
    {
        int tmp1 = l1->val;
        if (flag[i - 1])
        {
            tmp1++;
        }
        if (tmp1 >= 10)
        {
            flag[i] = 1;
            tmp1 -= 10;
        }
        ans[i - 1] = tmp1;

        i++;
        l1 = l1->next;
    }
    while (l2 != NULL)
    {
        int tmp2 = l2->val;
        if (flag[i - 1])
        {
            tmp2++;
        }
        if (tmp2 >= 10)
        {
            flag[i] = 1;
            tmp2 -= 10;
        }
        ans[i - 1] = tmp2;

        i++;


        l2 = l2->next;
    }


    //最后有i-1个数
    //ans数组记录到下标位i-2
    //flag数组记录到下标为i-1


    if (flag[i - 1])
    {
        ans[i - 1] = 1;
        i++;
    }

    //最后有i-1个数

    ListNode* win = new ListNode(ans[0]);
    ListNode* tmpNode = win;
    for (int index = 1; index < i - 1; index++)     //由ans数组建立链表
    {
        ListNode* s = new ListNode(ans[index]);
        tmpNode->next = s;
        tmpNode = s;
    }
    return win;
}


int main()     //测试用例,重点是上面的函数
{
    ListNode* a = new ListNode;
    a->val = 1;
    ListNode* aa = new ListNode;
    a->next = aa;
    aa->val = 9;
    ListNode* aaa = new ListNode;
    aa->next = aaa;
    aaa->val = 9;
    ListNode* b = new ListNode;
    aaa->next = b;
    b->val = 9;
    ListNode* bb = new ListNode;
    b->next = bb;
    bb->val = 9;
    ListNode* bbb = new ListNode;
    bbb->val = 9;
    bb->next = bbb;
    ListNode* c = new ListNode;
    c->val = 9;
    bbb->next = c;
    ListNode* cc = new ListNode;
    cc->val = 9;
    c->next = cc;
    ListNode* ccc = new ListNode;
    ccc->val = 9;
    cc->next = ccc;
    ListNode* d = new ListNode;
    d->val = 9;
    ccc->next = d;
    ListNode* ans = new ListNode;
    ListNode* win = new ListNode;
    win->val = 9;
    ans = addTwoNumbers(a, win);
    while(ans != NULL)
    {
        cout << ans->val;
        ans = ans->next;
    }
}

运行结果:00000000001

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值