两个数相加问题 - Java 解决方案

文章介绍了如何使用链接列表解决两个反向存储的非负整数相加的问题,通过模拟纸上的加法过程,从右侧开始逐位相加,并处理进位,最终构建新的链表返回结果。解决方案的时间复杂度和空间复杂度均为O(max(m,n)),其中m和n分别为两个输入链表的长度。这种方法强调了在编写代码前先用伪代码解决问题的重要性。
摘要由CSDN通过智能技术生成

“两个数字相加”问题是您在 LeetCode 等各种编码挑战网站上都会发现的常见问题。这个问题很好地介绍了如何使用链接列表,并且需要使用两个链接列表来创建第三个列表。为了解决此类问题,在深入研究代码之前考虑一下如何在纸上解决它会很有帮助。

问题陈述

给您两个表示两个非负整数的非空链表。数字以相反的顺序存储,每个节点包含一个数字。将两个数字相加并以链表形式返回总和。

您可以假设这两个数字不包含任何前导零,除了数字 0 本身。

例子:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)

Output: 7 -> 0 -> 8

Explanation: 342 + 465 = 807.

方法

问题表明数字以相反的顺序存储。这让我停顿了一分钟;然而,它实际上使解决这个问题变得更容易。如果我们在纸上写下两个数字相加的问题,我们就会以相反的顺序将它们相加。

// To add these numbers we would start from the
// right side (in reverse order)
 342
+465
----
 807

思考如何将两个数字加在一起可以帮助我们想出一种算法来解决这个问题。只需迭代两个列表并将每个数字相加(模拟从右侧开始)即可。如果一个数字有更多位数,我们很有可能必须检查是否为空。而且,如果两个数字之和大于 9,我们还必须处理结转。有关更多详细信息,请参阅下面代码中的注释。

/**

  • 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; }
    }
    /
    *

  • Solution
    */
    class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    // Head of the new Linked List - this will be the result
    ListNode result = new ListNode();
    // Reference of the result, which is empty at this point
    ListNode pointer = result;
    // Carry over number
    int carry = 0;

     while(l1 != null || l2 != null) {
         // if either value is null, use zero else use value
         int x = l1 == null ? 0 : l1.val;
         int y = l2 == null ? 0 : l2.val;
         // do the adding
         int sum = x + y + carry;
         // calculate the carryover. Remember this is
         // integer division and will only return whole 
         // numbers. 
         carry = sum / 10;
         // At this point we add the total sum mod 10 to
         // the new node in the results list. If the
         // integer is greater than 10 this will return
         // the remainder. If its less than 10, it will
         // return the integer.
         pointer.next = new ListNode(sum % 10);
         pointer = pointer.next;
    
         // Move to next node
         if (l1 != null) {
             l1 = l1.next;
         }
         if (l2 != null) {
             l2 = l2.next;
         }
     }
     // After the last iteration, check to see if there is
     // a carryover left, if so, add it to the results
     // list
     if (carry != 0) {
         pointer.next = new ListNode(carry);
     }
    
     return result.next;
    

    }
    }

复杂

现在我们可以计算出解决方案的复杂性。

时间复杂度

l1如果is的长度和ism的长度,则上面的解决方案将迭代 m 或 n 次。这给出了O(max(m, n))的时间复杂度。l2n

空间复杂度

O(max(m, n)),因为我们正在创建一个新的链表来返回。

最后的想法

通过思考如何将两个数字加在一起,您可以想出一种算法来处理此类问题。在某些情况下,可以通过思考如何解决“现实生活”中的问题而不是使用编程语言来找到初步解决方案。这就是为什么代码挑战专家建议在进入实际代码之前使用纸张和 sudo 代码解决问题的原因之一。这种技术可以帮助您思考问题本身而不是实现。上述解决方案只是解决该问题的一种方法。

关注我的博客,您将在其中获得提示、技巧和挑战,以保持您的技能敏锐。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Q shen

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

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

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

打赏作者

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

抵扣说明:

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

余额充值