2,两数相加 - 链表表示法

在这篇文章中,我们将探讨一个有趣的算法问题:给定两个非空的链表,它们表示两个非负整数。我们的目标是将这两个数相加,并返回一个新的链表,以表示它们的和。

问题背景

给定两个非空链表 l1 和 l2,它们分别代表两个非负整数。链表中的每个节点存储一个数字,并按逆序方式组织,即链表的头部表示数字的个位。

我们的任务是将这两个数字相加,并返回一个新的链表,其中每个节点包含新数字的一个数字位。

示例

  • 示例 1:l1 = [2,4,3], l2 = [5,6,4],输出 [7,0,8],表示 342 + 465 = 807。
  • 示例 2:l1 = [0], l2 = [0],输出 [0],表示 0 + 0 = 0。
  • 示例 3:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9],输出 [8,9,9,9,0,0,0,1],表示 9999999 + 9999 = 10009998。

解题思路

我们可以通过遍历两个链表来模拟加法运算。初始化一个新链表来存储结果,使用一个指针从链表头部开始逐位相加,并考虑进位的情况。

代码实现

下面是使用 Java 实现的解决方案:

class ListNode {
    int val;
    ListNode next;
    
    ListNode(int val) {
        this.val = val;
    }
}

public class AddTwoNumbers {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        // 创建一个虚拟节点,简化链表操作
        ListNode dummy = new ListNode(0);
        ListNode current = dummy; // 指针用于遍历新链表
        int carry = 0; // 进位标志

        while (l1 != null || l2 != null) {
            // 获取当前节点的值(若为空则取0)
            int x = (l1 != null) ? l1.val : 0;
            int y = (l2 != null) ? l2.val : 0;

            // 计算当前位数字的和(包括进位)
            int sum = x + y + carry;
            carry = sum / 10; // 更新进位
            current.next = new ListNode(sum % 10); // 创建新节点,存储结果
            current = current.next; // 指针后移

            // 遍历链表
            if (l1 != null) l1 = l1.next;
            if (l2 != null) l2 = l2.next;
        }

        // 检查是否有额外的进位,若有则创建新节点
        if (carry > 0) {
            current.next = new ListNode(carry);
        }

        return dummy.next; // 返回结果链表的头部
    }
}

总结

这个例子展示了如何通过链表表示逆序整数,并模拟数字相加的过程,最终得到新的链表表示结果。这个问题有助于加深对链表操作和数学运算的理解。希望这次讨论能为你提供新的见解!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,这是一道经典的链表题目,我们可以使用一个变量来记录进位,然后按位相加即可。以下是示例代码: ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def addTwoNumbers(l1: ListNode, l2: ListNode) -> ListNode: dummy = ListNode() curr = dummy carry = 0 while l1 or l2 or carry: val1 = l1.val if l1 else 0 val2 = l2.val if l2 else 0 carry, val = divmod(val1 + val2 + carry, 10) curr.next = ListNode(val) curr = curr.next l1 = l1.next if l1 else None l2 = l2.next if l2 else None return dummy.next ``` 这个函数接受两个链表作为输入,返回一个新的链表表示它们的和。我们使用 dummy 节点来简化代码,curr 指向当前节点,carry 记录进位。在循环中,我们分别取出两个链表当前节点的值,加上进位,然后计算进位和当前位的值。将当前位的值插入到新链表中,然后将 curr 指向新的节点。最后返回 dummy.next 即可。 接下来是 "lua closure factory 完整代码" 的答案: ```lua function make_counter() local count = 0 return function() count = count + 1 return count end end c1 = make_counter() print(c1()) -- 输出 1 print(c1()) -- 输出 2 print(c1()) -- 输出 3 ``` 这是一个简单的闭包工厂函数,它返回一个闭包,每次调用闭包时返回一个递增的计数器值。在这个示例中,我们定义了一个局部变量 count,然后返回一个匿名函数,该函数在每次调用时将 count 加 1 并返回它的值。我们可以使用 make_counter 函数创建多个计数器,它们之间是相互独立的。 最后是 "中文加密" 的答案: 中文加密是指将中文文本转换为一串密文,使得只有掌握密钥的人才能够解密。常见的中文加密算法包括 DES、AES、RSA 等。这些算法都是基于数学原理设计的,可以保证加密后的数据安全性。 如果你想要自己实现一个简单的中文加密算法,可以考虑使用替换法。例如,将每个中文字符替换为另一个字符或者字符串,然后将替换后的文本作为密文。解密时,将密文中的字符再替换回来即可。这种方法的安全性较低,容易被破解,但可以用于一些简单的加密场景。 ### 回答2: 题目要求将两个非负整数的链表表示相加,并以相同形式返回一个表示和的链表。假设链表中每个节点只能存储一位数字,且数字的存储顺序是逆序的。除了数字0之外,两个数都不会以0开头。 思路: 1. 定义一个dummy节点作为结果链表的头节点,并定义一个进位carry,默认为0。 2. 遍历两个链表,依次将对应位置的数字相加,并加上进位carry值。 3. 计算当前位置的数值sum,以及新的进位carry。如果sum大于等于10,则将sum减去10,并将carry置为1;否则,carry置为0。 4. 创建一个新的节点,并将sum作为新节点的值。 5. 将新节点插入结果链表的最后。 6. 判断两个链表是否还有剩余,若有,则继续遍历剩余部分的链表进行相加操作,直至两个链表都为空。 7. 若遍历结束时carry为1,则在结果链表的最后新增一个值为1的节点,表示进位的值。 8. 返回结果链表的头节点,即dummy.next。 代码如下: ```python def addTwoNumbers(l1, l2): dummy = ListNode(0) # 结果链表的头节点 curr = dummy # 当前节点 carry = 0 # 进位值 while l1 or l2: x = l1.val if l1 else 0 y = l2.val if l2 else 0 # 计算当前位置的和与新的进位 sum = carry + x + y carry = sum // 10 # 创建新的节点,并插入结果链表末尾 curr.next = ListNode(sum % 10) curr = curr.next # 遍历下一个位置 if l1: l1 = l1.next if l2: l2 = l2.next if carry == 1: # 若最后还有进位 curr.next = ListNode(1) return dummy.next # 返回结果链表的头节点 ``` 该算法的时间复杂度为O(max(m, n)),其中m和n分别为两个链表的长度。算法需要遍历两个链表中较长的那个链表,并额外的空间复杂度为O(max(m, n))。 ### 回答3: 题目要求将两个用链表表示的非负整数相加,每位数字按照逆序存储,并且每个节点只能存储一位数字。可以假设除了数字0之外,这两个数都不会以0开头。 可以使用链表的头插法来实现相加操作。 具体步骤如下: 1. 初始化一个新的链表节点,用来存储结果。 2. 初始化两个指针,分别指向两个链表的头节点。 3. 初始化一个进位值carry为0,用来表示相加时的进位。 4. 遍历两个链表,直到两个链表都为空。 - 将当前两个节点的值相加,并加上进位值carry。 - 计算当前位的数字为(sum + carry) % 10,carry为(sum + carry) / 10。 - 将计算得到的当前位数字作为新的节点插入到结果链表的头部。 - 更新指针,继续遍历下一位。 5. 如果遍历完两个链表后,进位值carry不为0,则将carry作为新的节点插入到结果链表的头部。 6. 返回结果链表。 下面是具体的代码实现: ```python class ListNode(): def __init__(self, val=0, next=None): self.val = val self.next = next def addTwoNumbers(l1: ListNode, l2: ListNode) -> ListNode: dummy = ListNode() # 初始的哑节点 result = dummy # 用于构建结果链表 carry = 0 # 进位值 while l1 or l2: x = l1.val if l1 else 0 y = l2.val if l2 else 0 sum = x + y + carry carry = sum // 10 result.next = ListNode(sum % 10) result = result.next if l1: l1 = l1.next if l2: l2 = l2.next if carry: result.next = ListNode(carry) return dummy.next ``` 这样就得到了表示结果的链表。需要注意的是,最后要返回结果链表的头节点,而不是哑节点dummy。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值