【LeetCode --2】两数相加 [C++]

题目描述

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

示例

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

解题思路

这里我会提供两个思路:

  1. 创建一个新链表add 并new 一个头结点,再创建一个链表的指针l3,将l1+l2各个位上的值分别相加,并存储在add链表的相应位置(先new新结点),若l1+l2最高位仍有进位,则再new一个新节点。否则直接返回链表的第一个结点就好。

2.(省空间) 先判断l1和l2哪个链表更长,就将计算结果直接存储在较长的链表中,万一 l1+l2最高位仍有进位,所以就在结尾先new一个新节点。若有进位直接返回,没进位则赋空再返回。

完整代码-1
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* add=new ListNode(0);   //创建新链表及头结点
        ListNode* l3=add;           //链表指针
        int nret=0;                   //存储进位
        while(l1!=NULL||l2!=NULL)
        {
            int ret=0;        //存储两个数相加的结果,每次ret都要更新
            if(l1!=NULL)
            {
                ret+=l1->val;     //将l1的值放在ret里
                l1=l1->next;        //l1的指针向后移
            }
            if(l2!=NULL)
            {
                ret+=l2->val;       //将l2的值放在ret里
                l2=l2->next;        //l2的指针向后移
            }
            ret+=nret;           //再加上进位的值
            if(ret>9)             //如果ret需要进位进位,则修改ret和nret的值  
            {
                ret-=10;         
                nret=1;
            }
            else nret=0;       //如果ret没有发生进位,则nret更新为0
            l3->next=new ListNode(1);      //为add链表创建下一个节点
            l3=l3->next;                      //使指针指向下一个节点
            l3->val=ret;                 //将ret存储在节点里
        }
        if(nret!=0)      //如果两数加完高位仍有进位,则新建结点存储进位
            l3->next=new ListNode(1);
         return add->next;     //否则直接返回add链表的第一个值
    }
};
完整代码-2
   bool AlongerB(ListNode* l1,ListNode* l2)//l1是否比l2长
    {
        while(l1)                
        {
            l1=l1->next;          //l1和l2指针同时后移
            l2=l2->next;
            if(l2==NULL)      //如果l1仍然有结点而l2已没有则返回true
                return true; 
        }
        return false;
    }
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode *add=l2;            //创建新链表指向l2
        if(AlongerB(l1,l2)) 
           add=l1;                  //如果ll比l2长,则新链表指向l1
        ListNode *l3=add;          //为新链表创建指针
        int nret=0;                 //存储进位
        while(l1||l2)
        {
            int ret=0;
            if(l1!=NULL)
            {
                ret+=l1->val;
                l1=l1->next;
            }
            if(l2!=NULL)
            {
                ret+=l2->val;
                l2=l2->next;
            }
            ret+=nret;
            if(ret>9)
            {
                ret-=10;
                nret=1;
            }
            else
                nret=0;
             l3->val=ret;        //将长链表中的值更新为ret
            if(l3->next)        //如果当前不是最后一个节点
               l3=l3->next;      //则继续计算下一个节点
            else
                l3->next=new ListNode(1);   //若是最后一个节点,则新建一个节点
        }
        if(nret==0)
            l3->next=NULL;       //如果最高位没有进位则将最后一个节点赋空
        return add;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值