leetcode 2. 两数相加

题目:

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

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

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

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例 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
题目数据保证列表表示的数字不含前导零

我们先观察,在行动

  1. 题意就是非负整数相加,就像我我们小学过的一样.    
  2. 但是这个链表是[逆序]的,和我们书写的逻辑不一样,但是计算的逻辑是一样的,这应该算是题目给我们留下的伏笔,方便我们利用链表的特性做数据处理.
  3. 需要关注的点应该就是进位问题,进位多出来的1需要进入下一次运算.而运算的过程依然是[相加],很容易让人连想到[递归逻辑].

上递归代码

    //这个是我们最后输出的链表
    public static ListNode targetNode = null;
    //写着写着就会发现我们需要一个tmp值去不断操作链表中的下一个valux
    public static ListNode tempNode = null;
    //进位标识,如果需要进位则参与下次运算
    public static int carry = 0;
    //循环标识符,用于退出循环
    public static Boolean loop = true;
    public static ListNode addTwoNumbers(ListNode l1, ListNode l2){
        while (loop){
            int sum = l1.val+l2.val+carry;
            //小学二年级我们就学过十进制加法位数相加,满10进一
            carry = sum /10;
            if (targetNode==null){
                //如果输出的链表为空,则新建一个链表,并且把进位后计算的值放入
                targetNode = tempNode=  new ListNode(sum%10);
            }else {
                //如果我们可爱的node不为空,就继续接上链表
                tempNode.next = new ListNode(sum%10);
                //为了方便我们递归后使用链表,所以temp链表向后移动
                tempNode = tempNode.next;
            }
            //只有入参的两个node都没有下一个链表后才会停止循环
            if (l1.next==null&&l2.next==null){
                loop =false;
            }else{
                //递归!
                addTwoNumbers(l1.next,l2.next);
            }
        }
                //千万别忘了最后一次处理carry进位的情况
            if (carry > 0) {
            tempNode.next = new ListNode(carry);
        }
         //操作结束后return目标链表
        return  targetNode;
    }

经过我的测试,我觉得可以了这题应该解出来了,信心满满的提交leetcode答案

啊?为什么?执行都没有错,提交就会出错?我是不是发现了leetcode的bug了?

 

这时候各位观众就会说:怎么只会这种逻辑简单的递归?连答案都没法提交?深沈你找个厂上班得了!

呜呜,为了不进厂上班我思考片刻,不用递归能不能行?! 上链接! 啊不,上代码!

public  static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode target = null,tail =null;
        int carry = 0;
        while (l1 != null || l2 != null) {
            int i = l1 != null ? l1.val : 0;
            int j = l2 != null ? l2.val : 0;
            int sum = i + j + carry;

            //这里需要一个标识位置,表示是否是第一次计算,如果是就新创建一个listnode如果不是就再之前的listnode进行连接
            if (target == null) {
                //创建一个node把处理结果的余数放里面
                target = tail = new ListNode(sum%10);
            }else{
                tail.next = new ListNode(sum%10);
                tail = tail.next;
            }
            //如果两数相加结果大于10的话 做/10 运算后会得到十位数,作为下一位的标识参与sum运算
            carry = sum/10 ;
            //相加的目标链表向后移动
            if (l1 != null) {
                l1 = l1.next;
            }
            if (l2 != null) {
                l2 = l2.next;
            }
        }
        //最后如果进位上还有值需要在链表后再加一段放carry值
        if (carry > 0) {
            tail.next = new ListNode(carry);
        }
        return target;

    }

核心逻辑上没有什么区别都需要循环判断,如果仔细理解了本题的意图的话还是比较简单就可以做出来的

希望看到这里的观众给深沈点个赞吧!

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值