LeetCode002-两数相加-medium

题目:给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字0之外,这两个数都不会以0开头

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

解题思路:

题中说各自的位数是按照逆序的方式存储到链表中,其实这降低了难度,因为刚好进行加法运算时,从个位开始加,而链表中从前到后是从低位开始的,刚好符合了加法的运算顺序(以题中给的数据为例)

既然是求和,那不难知道,取出两个链表中的每一个节点,然后进行求和(sum),如果大于10则记一个进位1,然后拿sum对10进行求余,得的到结果就是目标链表的第一个有效节点,具体过程如图:

实现过程:

1、核心方法就是对两个链表进行遍历,然后逐个节点求和

  • 因为不知道这两个要求和的链表的节点个数(也就是不知道循环次数),所以选择while循环。只要任何一个链表的节点不为null,都需要继续进行循环
  • 但是因为有进位的情况,所以,当进位不是0时,也不能停止循环(比如9999+1)

2、生成新的链表存储求和的结果

  • 对于链表的问题,通常都会创建一个标志节点,它不存具体的值,它的next负责指向第一个有效节点(始终指向第一个,不移动),主要是为了方便我们返回得到的目标链表
  • 同时需要创建一个current节点,他负责生成每一个节点,它是移动的,每生成一个节点,它都需要向后移动一个节点,从而实现构建新的链表

语言表达能力有点差,可能描述的不是很清楚,代码中有必要的注释,希望可以帮助理解

代码实现

class ListNode
{
    public $val = 0;
    public $next = null;
    public function __construct($val)
    {
        $this->val = $val;
    }
}

class LeetCode002
{
    /**
     * @param ListNode $l1
     * @param ListNode $l2
     * @return ListNode
     */
    public function addTwoNumbers($l1, $l2)
    {
        if ($l1 == null && $l2 == null) {
            return null;
        }

        $tag = new ListNode(0);//创建空节点
        $current = $tag;
        $addOne = 0;//进位
        while ($l1 != null || $l2 != null || $addOne != 0) {
            $val1 = $l1 == null ? 0 : $l1->val;
            $val2 = $l2 == null ? 0 : $l2->val;
            $sum = $val1 + $val2 + $addOne;
            $current->next = new ListNode($sum % 10);
            $current = $current->next;
            $addOne = intval($sum / 10);//坑,强类型语言不存在此问题
            if ($l1 != null) {
                $l1 = $l1->next;
            }
            if ($l2 != null) {
                $l2 = $l2->next;
            }
        }
        return $tag->next;
    }
}

//Test Case
$leetCode = new LeetCode002();
$l1 = new ListNode(2);
$l1->next = new ListNode(4);


$l2 = new ListNode(5);
$l2->next = new ListNode(6);

$newList = $leetCode->addTwoNumbers($l1, $l2);
$str = '';
while ($newList != null) {
    $str .= $newList->val.'->';
    $newList = $newList->next;
}

echo $str;

执行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HYvXTrXs-1596157723434)(https://imgkr2.cn-bj.ufileos.com/0e5487e6-8aa9-445d-867d-6d270a62a350.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=kk9GWabE%252FB3tWbmidbBUJqeBTu4%253D&Expires=1596243484)]

根据提供的引用内容,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、付费专栏及课程。

余额充值