LeetCode 题解 2 - JS TS PY 解法解锁:两数相加的艺术
2023-09-09 01:50:11
探索 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. 这个问题有什么现实应用?
两数相加问题在计算机科学和日常生活中都有广泛的应用,比如在高精度计算、大数加法器和密码学中。