Leetcode算法题-2.两数相加

问题描述

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

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

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

输入:l1 = [2,4,3], l2 = [5,6,4]

输出:[7,0,8]

解释:342 + 465 = 807.

个人初见解题思路

理解完题目要求后,本人产生了两种解题思路。

第一种:

将两个链表转成数字,相加求和,再将和转链表输出。

第二种:

按加法计算公式,每位相加。

第一种实现起来简单,但是有缺点,一旦链表长度超过语言能承受的最大数字长度,就万策尽了。

第二种方式可以解决第一种的问题,但是实现起来没有第一种简单。

先按照第一种方法来实现

public class Solution {
    public ListNode AddTwoNumbers(ListNode l1, ListNode l2){
        return NumToListNodeDesc(ListNodeToNum(l1) + ListNodeToNum(l2));
    }

    public long ListNodeToNum(ListNode<int> node)
    {
         var numStr = "";
         var currentNode = node;
         while (currentNode != null)
         {
             numStr = $"{currentNode.val}{numStr}";
             currentNode = currentNode.next;
         }
         return long.Parse(numStr);
    }

    public ListNode<int> NumToListNodeDesc(long num)
    {
         var numStr = num.ToString();
         ListNode<int> beforeNode = null;
         for (int i = 0; i <= numStr.Length - 1; i++)
         {
             var numVal = int.Parse(numStr[i].ToString());
             var node = new ListNode<int>(numVal, beforeNode);
             beforeNode = node;
         }
         return beforeNode;
     }
}

运行测试之后,长度短的链表没有问题,但是提交解题答案时候,不知道被多少亿的数值打爆了

所以,我们还得采用第二种解决方案

代码计算两数相加

在构思第二种解题思路的时候,突然发现,题目给的是逆序进来,要的返回结果,也是逆序出去,所以我们在计算的时候,其实没有必要去特意的把数字颠倒过来,因为 243 + 564 = 708,和预期链表结果708是一致的顺序,所以,题目本身的逆序就是烟雾弹。

加法思路:

我们需要从头开始遍历两个链表,把当前节点加起来求和,如果和大于10,下一次两个节点求和需要+1,如果遍历过程中有一个链表已经是空了,那么求和的时候把这个链表的值当0即可,另外的,还需要在整个链表遍历完成后,检查最后求和结果有没有超过10,如果超过了,还需要往前补1。

记录加法结果:

最初想的思路是在遍历列表的时候,建立一个List存储结果,链表遍历完成后,再List转链表,后面想了下,其实可以直接在求和的时候 ,通过移动当前node节点指针的方式,同步记录结果,不过这样需要注意的是,需要建立头部空节点,否则头部指针就丢失了。

最终实现如下:

public class Solution {
    public ListNode AddTwoNumbers(ListNode l1, ListNode l2) {
        var l1Access = l1;
        var l2Access = l2;
        var pre = new ListNode();
        var cur = pre;
        var overflow = 0;
        while (l1Access != null || l2Access != null)
        {
            var addRsp = (l1Access != null ? l1Access.val : 0) + (l2Access != null ? l2Access.val : 0) + overflow;

            overflow = addRsp / 10;

            cur.next = new ListNode(addRsp % 10);
            cur = cur.next;

            if (l1Access != null)
            {
                l1Access = l1Access.next;
            }
            if (l2Access != null)
            {
                l2Access = l2Access.next;
            }
        }
        if (overflow > 0)
        {
            cur.next = new ListNode(overflow);
        }
        return pre.next;
    }
}

提交运行,没有问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值