力扣刷题笔记(2)两数相加(C++)

题目描述

  • 给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。
  • 请你将两个数相加,并以相同形式返回一个表示和的链表。
  • 你可以假设除了数字0之外,这两个数都不会以0开头。

个人题解(1)

本人在第一次完成该题目时,使用了分情况讨论法。代码如下:

class Solution 
{
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) 
    {
        int jinwei(0);                        //记录每一次逐位相加的进位(只可能是0或1)
        ListNode* traverse(new ListNode());   //记录当前遍历到的加法结果位结点
        ListNode* result(traverse);           //记录最终的链表按位加法运算结果

        //通过一个无限循环进行加法计算
        while(true)
        {
            //情况1:两个链表当前位置均不为空,则进行按位加法
            if(l1!=nullptr && l2!=nullptr)
            {
                //进行按位加法,考虑到上一位的进位(出于程序逻辑简单,不单独考虑第一位)
                traverse->val = l1->val + l2->val + jinwei;
                //如果计算结果大于等于10,则进行进位记录处理,否则不进位
                if(traverse->val >= 10)
                {
                    traverse->val -= 10;
                    jinwei = 1;
                }
                else jinwei = 0;
                //修改l1和l2指针指向下一个结点
                l1 = l1->next;
                l2 = l2->next;
                //如果l1和l2都遍历完成,且没有进位,则直接返回结果(考虑到程序效率,编写代码时采用反逻辑)
                if(l1!=nullptr || l2!=nullptr || jinwei==1)
                {
                    traverse->next = new ListNode();
                    traverse = traverse->next;
                }
                else return result;
            }
            //情况2:L1链表的位置不为空且L2链表的位置为空
            else if(l1!=nullptr and l2==nullptr)
            {
                //进行按位加法,只加L1的部分
                traverse->val = l1->val + jinwei;
                //如果计算结果大于等于10,则进行进位记录处理,否则不进位
                if(traverse->val >= 10)
                {
                    traverse->val -= 10;
                    jinwei = 1;
                }
                else jinwei = 0;
                //修改l1指针指向下一个结点
                l1 = l1->next;
                //如果l1遍历完成,且没有进位,则直接返回结果,原理与上一种情况类似
                if(l1!=nullptr || jinwei==1)
                {
                    traverse->next = new ListNode();
                    traverse = traverse->next;
                }
                else return result;
            }
            //情况3:L2链表的位置不为空且L1链表的位置为空
            else if(l2!=nullptr and l1==nullptr)
            {
                //进行按位加法,只加L2的部分
                traverse->val = l2->val + jinwei;
                //如果计算结果大于等于10,则进行进位记录处理,否则不进位
                if(traverse->val >= 10)
                {
                    traverse->val -= 10;
                    jinwei = 1;
                }
                else jinwei = 0;
                //修改l2指针指向下一个结点
                l2 = l2->next;
                //如果l2遍历完成,且没有进位,则直接返回结果,原理与上一种情况类似
                if(l2!=nullptr || jinwei==1)
                {
                    traverse->next = new ListNode();
                    traverse = traverse->next;
                }
                else return result;
            }
            //情况4:两个链表的当前位置同时为空,则在判定是否需要进位后,即可退出循环
            else if(l1==nullptr && l2==nullptr)
            {
                if(jinwei==1)
                {
                    traverse->val = 1;
                }
                break;
            }
        }
    return result;
    }
};

个人题解(2)

看了力扣官方的题解以及众多大佬们的代码后,发现根本就没有必要进行复杂的分情况讨论,并且判定是否需要进位的代码可以进行进一步简化。得到的结论如下:

  • 如果能够使用一种统一的算法代替需要进行分情况讨论的算法,那么一定是更好的。
  • 能够使用三元运算符?:的地方就不要使用if语句,因为前者的执行效率更高。

经过修改后的代码如下:

class Solution 
{
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) 
    {
        //记录两个数字相加时可能的进位(只能是0或1)
        int jinwei(0);      
        //分别记录两个链表的当前数字以及求和结果      
        int element1,element2,sum;
        //分别记录结果链表中的遍历位置和结果
        ListNode* traverse(nullptr);
        ListNode* result;

        //只要两个链表有一个链表中还有元素,则继续循环
        while(l1 || l2)
        {
            //分别取出两个链表中的下一个数字,如果不存在下一个元素则用0表示
            element1 = l1?l1->val:0;
            element2 = l2?l2->val:0;
            //进行相加求和
            sum = element1 + element2 + jinwei;
            //判断是否需要进行进位
            jinwei = sum / 10;
            //修改两个链表的指针位置
            if(l1)l1 = l1 -> next;
            if(l2)l2 = l2 -> next;
            //修改结果链表的指针(需要分指针是否为空的情况)
            if(!traverse)
            {
                traverse = new ListNode(sum % 10);
                result = traverse;
            } 
            else
            {
                traverse -> next = new ListNode(sum % 10);
                traverse = traverse -> next;
            }
        }
        //判断最后一位是否有进位
        if(jinwei==1) traverse -> next = new ListNode(1);
        //返回结果
        return result;
    }
};

另外,C++的语法学习上,有一个注意点:

  • 指针转换为布尔值:C++中,如果将一个非空指针转换为布尔值,则结果为true;如果将一个空指针转换为布尔值,则结果为false。
  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值