LeetCode - 2 / 445 / 剑指offer25 - 链表中的二个数字相加(详细)

声明:此类题为力扣链表编号为 2,445,以及剑指offer的第25题
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

文章前言

相同点:我们仔细阅读过上面的题后,发现他们其实都是一道题,就是两个链表的每个结点数值相加后组成的一个新的链表
不同点:第一道题,新链表的每个结点的数值和两个链表加和的结果顺序是一致的
不同点:第二题和剑指offer的题目,新链表的每个结点的数值和两个链表逆置后加和的结果顺序是一致的
图解区别:

在这里插入图片描述
剑指offer和编号445题:

在这里插入图片描述

总的来说:二者差的就是一步逆序的过程
题目大体思路:
步骤一、分别遍历两个链表,加和他们的数值
处理特殊情况:如果哪个链表为空,再次加和就是另一个没有空的链表的结点数值 + 0 + 前面数值加和的进位
图解:

在这里插入图片描述

代码表述:

在这里插入图片描述

步骤二、处理进位问题
如果两个数值加和后 ≥ 10,我们注意到两个链表的数值都是 0~9 的数值,所以 sum 的范围是[0,18],所以进位最多也就是 1 ,所以记录进位的 carry 只能是在 0 ,1 两个数字间徘徊
所以,当加和后大于等于 10 的时候就存在进位的问题,进位的 1 是加在下一位的加和结果中,当前位置的加和结果是 sum % 10 的结果,利用此 sum 去实例化一个新的结点

在这里插入图片描述

代码表述:

在这里插入图片描述

处理特殊的进位情况,如果最高位存在进位,假设 3 位数 999 + 1 进一位要变成 4 位数 1000,这样就还需要new一个结点

在这里插入图片描述

全部代码:
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        int carry = 0;
        ListNode newHead = new ListNode(0);
        ListNode tmp = newHead;
        while(l1 != null || l2 != null){
            int num1 = l1 != null ? l1.val : 0;
            int num2 = l2 != null ? l2.val : 0;
            int sum = num1 + num2 + carry;
            carry = sum / 10;
            ListNode node = new ListNode(sum % 10);
            tmp.next = node;
            l1 = l1 != null ? l1.next : l1;
            l2 = l2 != null ? l2.next : l2;
            tmp = tmp.next;
        }
        if (carry == 1){
            ListNode node = new ListNode(carry);
            tmp.next = node;
        }
        return newHead.next;
    }
}

成果展示:

在这里插入图片描述

剑指offer 25、编号445这两道题就是多一步,逆置操作

在这里插入图片描述

全部代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
     public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        l1 = reserve(l1); 
        l2 = reserve(l2);
        // 进位
        int carry = 0;
        ListNode newHead = new ListNode(0);
        ListNode tmp = newHead;
        while(l1 != null || l2 != null){
            int num1 = l1 != null ? l1.val : 0;
            int num2 = l2 != null ? l2.val : 0;
            int sum = num1 + num2 + carry;
            carry = sum / 10;
            tmp.next = new ListNode(sum % 10);
            l1 = l1 != null ? l1.next : l1;
            l2 = l2 != null ? l2.next : l2;
            tmp = tmp.next;
        }
        if (carry != 0){
            tmp.next = new ListNode(carry);
        }
        return reserve(newHead.next);
    }
    public ListNode reserve(ListNode node) {
        ListNode prev = null;
        while(node != null) {
            ListNode next = node.next;
            node.next = prev;
            prev = node;
            node = next;
        }
        return prev;
}
}

在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦の澜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值