LeetCode 链表两数相加⭐️

题目描述

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

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

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

示例 1:

输入: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
  • 题目数据保证列表表示的数字不含前导零

题目解析

上边题目这么多,其实就是两个数用链表倒序表示,然后对应位置相加,如果和大于10,就进位,最终要返回新的链表表示两数之和

思路

可以使用模拟的方法,两个链表对应位置相加,只是特殊场景比较多,此外还涉及到最终场景是否进位,是否需要创建链表对象。

定义指针分别指向链表的第一个元素处,然后依次计算对应位置和的场景。

正常情况,指针指向链表1和2的相同位置,如果指针指向的都非null,那么就先计算和,然后指针1和2都后移,

计算完后移动链表1和2的位置

如果其中一个为null,和的运算也只需要计算不为null的那个,只需要不为null的指针后移

比如

还需要定义两个变量addNum 表示进位的数,没有进位就是0,currentVal,表示当前位置上计算后的值,比如2+3,是5,如果超过10,比如7+6,addNum就是1,currentVal=3

然后就是将表示结果的链表指针,赋值val为currentVal

current1和current2已经后移了

同时这里需要处理好最后一个节点的场景,此时需要注意,current1和current2已经指向了下一个元素了

如果current1和current2指向至少一个不为null,那么说明肯定有下一个和,也就肯定有下一轮的计算

所以,创建一个指针表示结果指向的next,然后将当前指针后移

如果两个都为空,那么还需要根据addNum,区分是否创建下一个元素

addNum=0就不用了说明已经到达了结尾,直接返回即可

addNum!=0,说明还有最后一个元素,需要创建一个节点,然后再返回

/**
 * 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) {
        ListNode current1 = l1; //定义指针指向l1
        ListNode current2 = l2;//定义指针指向l1
        ListNode l3 = new ListNode(0, null); //定义指针指向l3
        ListNode l3H = new ListNode(0, l3);//定义虚拟头指向l3
        int addNum = 0;//进位
        while (current1 != null || current2 != null) {//结束条件,两个指针都指向了空
            int he = 0;//对应位置和
            //都不为null
            if (current1 != null && current2 != null) {
                //计算和
                he = current1.val + current2.val + addNum;
                //后移指针
                current1 = current1.next;
                current2 = current2.next;
            } else if (current1 == null && current2 != null) {
                //current1=null;计算和,移动current2
                he = current2.val + addNum;
                current2 = current2.next;
            } else if (current2 == null && current1 != null) {
                //current2=null;计算和,移动current1
                he = current1.val + addNum;
                current1 = current1.next;
            }
            //当前位置值
            int currenVal = 0;
            //和大于=10,记进位1,当前位置值为取模
            if (he >= 10) {
                addNum = 1;
                currenVal = he % 10;
            } else {
                //小于10,进位0,当前值就是和
                addNum = 0;
                currenVal = he;
            }
            l3.val = currenVal;//l3赋值
            //下一个指针指向的都是null,说明已经到了结尾
            if (current1 == null && current2 == null) {
                //进位决定是否需要再添加一个末尾元素,如最后是9+9,还需要再添加一个末尾元素
                if (addNum != 0) {
                    ListNode listNode = new ListNode(addNum, null);
                    l3.next = listNode;
                } else {
                    //没有就直接指向null
                    l3.next = null;

                }
                //已经到了末尾返回即可
                return l3H.next;
            } else {
                //下一个指针指向的至少一个不是null,创建指针,next指向下一个,然后移动l3,进入下一轮循环
                ListNode next = new ListNode(0, null);
                l3.next = next;
                l3 = next;
            }

        }
        return l3H.next;
    }
}

不用虚拟头指针的方法,定义指针变量p,指向l3

/**
 * 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) {
        ListNode current1 = l1; //定义指针指向l1
        ListNode current2 = l2;//定义指针指向l1
        ListNode l3 = new ListNode(0, null); //定义指针指向l3
        ListNode p =l3;
        int addNum = 0;//进位
        while (current1 != null || current2 != null) {//结束条件,两个指针都指向了空
            int he = 0;//对应位置和
            //都不为null
            if (current1 != null && current2 != null) {
                //计算和
                he = current1.val + current2.val + addNum;
                //后移指针
                current1 = current1.next;
                current2 = current2.next;
            } else if (current1 == null && current2 != null) {
                //current1=null;计算和,移动current2
                he = current2.val + addNum;
                current2 = current2.next;
            } else if (current2 == null && current1 != null) {
                //current2=null;计算和,移动current1
                he = current1.val + addNum;
                current1 = current1.next;
            }
            //当前位置值
            int currenVal = 0;
            //和大于=10,记进位1,当前位置值为取模
            if (he >= 10) {
                addNum = 1;
                currenVal = he % 10;
            } else {
                //小于10,进位0,当前值就是和
                addNum = 0;
                currenVal = he;
            }
            p.val = currenVal;//l3赋值
            //下一个指针指向的都是null,说明已经到了结尾
            if (current1 == null && current2 == null) {
                //进位决定是否需要再添加一个末尾元素,如最后是9+9,还需要再添加一个末尾元素
                if (addNum != 0) {
                    ListNode listNode = new ListNode(addNum, null);
                    p.next = listNode;
                } else {
                    //没有就直接指向null
                    p.next = null;

                }
                //已经到了末尾返回即可
                return l3;
            } else {
                //下一个指针指向的至少一个不是null,创建指针,next指向下一个,然后移动l3,进入下一轮循环
                ListNode next = new ListNode(0, null);
                p.next = next;
                p = next;
            }

        }
        return l3;
    }
}

根据提供的引用内容,Leetcode 2 "两数相加"是一个涉及链表的问题。该问题给定了两个非负整数,每个整数的每一位都是按照逆序的方式存储在链表中。我们需要将这两个链表相加,并返回一个新的链表作为结果。 具体解题思路可以使用迭代法或递归法来解决。迭代法的伪代码如下所示: ``` 初始化一个哑节点 dummy 和一个进位 carry,同时把两个链表的头节点分别赋值给 p 和 q 遍历链表,直到 p 和 q 都为 None 计算当前的和 sum 为 p.val + q.val + carry 计算当前的进位 carry 为 sum // 10 创建一个新节点 node,节点的值为 sum % 10 把新节点连接到结果链表的尾部 更新 p 和 q 分别为 p.next 和 q.next 如果最后还有进位 carry,则创建一个新节点 node,节点的值为 carry,并连接到结果链表的尾部 返回结果链表的头节点 dummy.next ``` 递归法的伪代码如下所示: ``` 定义一个辅助函数 addTwoNumbersHelper,输入为两个链表的头节点 p 和 q,以及进位 carry 如果 p 和 q 都为 None 且 进位 carry 为 0,则返回 None 计算当前的和 sum 为 p.val + q.val + carry 计算当前的进位 carry 为 sum // 10 创建一个新节点 node,节点的值为 sum % 10 设置新节点的下一个节点为递归调用 addTwoNumbersHelper(p.next, q.next, carry) 返回新节点 返回 addTwoNumbersHelper(p, q, 0) 的结果 以上是解决 Leetcode 2 "两数相加"问题的两种方法。如果你还有其他相关问题,请
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值