题目描述

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

  1. 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
  2. 输出:7 -> 0 -> 8
  3. 原因:342 + 465 = 807

题解

思路

我们使用变量来跟踪进位,并从包含最低有效位的表头开始模拟逐位相加的过程。
002 两数相加 - 图1
图1,对两数相加方法的可视化: 342 + 465 = 807342+465=807, 每个结点都包含一个数字,并且数字按位逆序存储。

算法

就像你在纸上计算两个数字的和那样,我们首先从最低有效位也就是列表 l1l1 和 l2l2 的表头开始相加。由于每位数字都应当处于 0 \ldots 90…9 的范围内,我们计算两个数字的和时可能会出现“溢出”。例如,5 + 7 = 125+7=12。在这种情况下,我们会将当前位的数值设置为 22,并将进位 carry = 1carry=1 带入下一次迭代。进位 carrycarry 必定是 00 或 11,这是因为两个数字相加(考虑到进位)可能出现的最大和为 9 + 9 + 1 = 199+9+1=19。

  1. public class Solution
  2. {
  3. public ListNode AddTwoNumbers(ListNode l1, ListNode l2)
  4. {
  5. var head = new ListNode(0);
  6. var point = head;
  7. int carry = 0;
  8. while (l1 != null || l2 != null)
  9. {
  10. var x = l1?.val ?? 0;
  11. var y = l2?.val ?? 0;
  12. var digit = carry + x + y;
  13. carry = digit / 10;
  14. point.next = new ListNode(digit % 10);
  15. point = point.next;
  16. l1 = l1?.next;
  17. l2 = l2?.next;
  18. }
  19. if (carry > 0) { point.next = new ListNode(carry); }
  20. return head.next;
  21. }
  22. }