返回

5 分钟学会两数相加进阶算法,轻松应对 LeetCode 挑战

前端

深入探索两数相加算法:链表操作与算法思维的进阶指南

序言

算法世界的大门已经向你敞开,而两数相加算法就是你踏入这一迷人领域的敲门砖。作为前端开发者,你可能对 LeetCode 上琳琅满目的算法问题望而生畏。别担心,本文将手把手带你深入理解两数相加算法,让你轻松应对 LeetCode 挑战,解锁算法思维的奥秘。

算法原理

想象一下,你手中有两个珠算,每个珠算上有若干个珠子,每个珠子代表一个数字。两数相加算法的任务是将这两个珠算上的珠子逐个相加,得到一个新的珠算作为结果。

在算法中,珠算上的珠子被抽象成链表中的节点,每个节点包含一个值和指向下一个节点的指针。相加过程从两个链表的头节点开始,逐个相加节点值,并考虑进位的情况。

例如,如果珠算上有 243 和 564 两个数,算法将从这两个数的个位数 3 和 4 开始相加,得到 7。由于 7 小于 10,因此将其作为结果珠算的第一个珠子。接下来,算法继续相加 4 和 6,得到 10。由于 10 大于或等于 10,算法将个位数 0 放到结果珠算上,并将十位数 1 进位到下一个珠子。

实现步骤

1. 定义链表节点结构

class ListNode {
  constructor(val, next) {
    this.val = val === undefined ? 0 : val;
    this.next = next === undefined ? null : next;
  }
}

2. 实现两数相加算法

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

  while (l1 || l2) {
    const sum = (l1?.val || 0) + (l2?.val || 0) + carry;
    if (sum < 10) {
      current.next = new ListNode(sum);
    } else {
      current.next = new ListNode(sum % 10);
      carry = Math.floor(sum / 10);
    }
    l1 = l1?.next;
    l2 = l2?.next;
    current = current.next;
  }

  if (carry > 0) {
    current.next = new ListNode(carry);
  }

  return dummy.next;
}

3. 测试算法

const l1 = new ListNode(2, new ListNode(4, new ListNode(3)));
const l2 = new ListNode(5, new ListNode(6, new ListNode(4)));
const result = addTwoNumbers(l1, l2);
console.log(result);

结语

通过本文的深入解析,你已经掌握了两数相加算法的精髓。它不仅是一道 LeetCode 经典题,更是一种算法思维的训练。它教会我们如何抽象问题,分解复杂任务,并逐步解决问题。

常见问题解答

  1. 算法的复杂度是多少?

    • O(max(m, n)),其中 m 和 n 是两个链表的长度。
  2. 如何处理两个链表长度不同的情况?

    • 将较短的链表用 0 填充,这样两个链表的长度相同。
  3. 算法是否可以处理负数?

    • 否,算法只能处理非负整数。
  4. 算法可以扩展到多个链表吗?

    • 是的,可以通过递归或循环的方式将算法扩展到多个链表。
  5. 算法在实际应用中有哪些场景?

    • 进制转换、大数相加、多项式相乘等。