返回

LeetCode 题解 2 - JS TS PY 解法解锁:两数相加的艺术

前端

探索 LeetCode 两数相加问题:三种语言,多重解法

导言

踏上算法解谜的征程,我们来到了 LeetCode 两数相加问题,这是一个既经典又富有挑战性的题目。在这场探索之旅中,我们将用 JavaScript (JS)、TypeScript (TS) 和 Python (PY) 三种语言,深入剖析不同的算法,并提供清晰易懂的解决方案。

问题概况

想象一下,你面前摆着两个链表,它们代表着两个非负整数,其中数字以逆序排列。你的任务是将这两个数相加,并返回一个新的链表,表示它们的和。为了增加挑战,这些数字绝不会以 0 开头。

算法解析

1. 逐位相加法

这是一个直观的解法,我们将链表的尾部节点相加,如果结果大于等于 10,则将进位存储在新的链表中。这种方法易于理解,但时间复杂度为 O(max(m, n)),其中 m 和 n 分别是两个链表的长度。

2. 递归法

递归是另一种解决此问题的策略。我们将两个链表分为两半,递归地计算每个半链表的和,然后将结果相加得到最终结果。递归法的优点是时间复杂度为 O(log(max(m, n))),比逐位相加法更高效。

3. 迭代法

迭代法采用与逐位相加法相似的步骤,但使用循环代替递归。我们将两个链表的节点逐一遍历,并根据需要处理进位。迭代法的时间复杂度与逐位相加法相同,但实现更加简洁。

代码实现

JavaScript

const addTwoNumbers = (l1, l2) => {
  let dummy = new ListNode(0);
  let current = dummy;
  let carry = 0;

  while (l1 || l2 || carry) {
    const val1 = l1 ? l1.val : 0;
    const val2 = l2 ? l2.val : 0;
    const sum = val1 + val2 + carry;
    carry = Math.floor(sum / 10);
    current.next = new ListNode(sum % 10);
    current = current.next;
    l1 = l1 ? l1.next : null;
    l2 = l2 ? l2.next : null;
  }

  return dummy.next;
};

TypeScript

const addTwoNumbers = (l1: ListNode, l2: ListNode): ListNode => {
  const dummy = new ListNode(0);
  let current = dummy;
  let carry = 0;

  while (l1 || l2 || carry) {
    const val1 = l1 ? l1.val : 0;
    const val2 = l2 ? l2.val : 0;
    const sum = val1 + val2 + carry;
    carry = Math.floor(sum / 10);
    current.next = new ListNode(sum % 10);
    current = current.next;
    l1 = l1 ? l1.next : null;
    l2 = l2 ? l2.next : null;
  }

  return dummy.next;
};

Python

def addTwoNumbers(l1: ListNode, l2: ListNode) -> ListNode:
    dummy = ListNode(0)
    current = dummy
    carry = 0

    while l1 or l2 or carry:
        val1 = l1.val if l1 else 0
        val2 = l2.val if l2 else 0
        sum = val1 + val2 + carry
        carry = sum // 10
        current.next = ListNode(sum % 10)
        current = current.next
        l1 = l1.next if l1 else None
        l2 = l2.next if l2 else None

    return dummy.next

总结

LeetCode 两数相加问题为我们提供了探索不同算法和数据结构的绝佳机会。通过逐位相加法、递归法和迭代法的对比,我们可以深入理解它们的优缺点,并根据具体情况选择最合适的方法。

常见问题解答

1. 如何处理链表长度不一致的情况?

如果两个链表长度不一致,我们将较短的链表的剩余节点补 0。

2. 如何防止数字溢出?

对于大数相加,我们需要使用特殊的算法,如 Karatsuba 算法或 Schönhage-Strassen 算法。

3. 是否可以用栈或队列来解决这个问题?

可以,但链表的实现通常更简洁高效。

4. 有没有更快的算法?

存在更快的算法,如 Cooley-Tukey FFT,但它们通常更复杂。

5. 这个问题有什么现实应用?

两数相加问题在计算机科学和日常生活中都有广泛的应用,比如在高精度计算、大数加法器和密码学中。