题目

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:
2. 两数相加(中等) - 图1
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

示例 2:
输入:l1 = [0], l2 = [0]
输出:[0]

示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]


提示:

  • 每个链表中的节点数在范围 [1, 100]
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零

解题思路

1、模拟计算(不可行)

分别遍历两个链表,计算两个操作数是多少,求和后再逐位生成新的链表。

模拟计算的方式首先于数据类型的限制,无法用于大数加法。这个思路事实上是一个死胡同,无法解决问题。

2、逐位计算

因为两个链表存储的每位数字都是按照 逆序 的方式存储,所以可以利用大数加法的思想,只维护一个进位变量,逐位计算。

答案

1、模拟计算(不可行)

虽然这个答案是错误的,但也记录一下。

  1. class Solution {
  2. public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
  3. // 两个操作数
  4. int a = 0, b = 0;
  5. // 求 a
  6. int multiples = 1;
  7. while (true) {
  8. if (l1.next != null) {
  9. a += l1.val * multiples;
  10. multiples *= 10;
  11. l1 = l1.next;
  12. continue;
  13. }
  14. a += l1.val * multiples;
  15. multiples = 1;
  16. break;
  17. }
  18. // 求 b
  19. while (true) {
  20. if (l2.next != null) {
  21. b += l2.val * multiples;
  22. multiples *= 10;
  23. l2 = l2.next;
  24. continue;
  25. }
  26. b += l2.val * multiples;
  27. break;
  28. }
  29. // 求 a + b 的和
  30. int sum = a + b;
  31. // System.out.println(a);
  32. // System.out.println(b);
  33. // System.out.println(sum);
  34. // 生成链表
  35. ListNode result = new ListNode();
  36. ListNode current = result;
  37. int temp = 0;
  38. while (true) {
  39. if (sum >= 10) {
  40. temp = sum % 10;
  41. sum /= 10;
  42. current.val = (int) temp;
  43. ListNode newNode = new ListNode();
  44. current.next = newNode;
  45. current = newNode;
  46. continue;
  47. } else {
  48. temp = sum;
  49. current.val = (int) temp;
  50. break;
  51. }
  52. }
  53. // System.out.println(result);
  54. return result;
  55. }
  56. }

2、逐位计算

  1. class Solution {
  2. public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
  3. ListNode root = new ListNode(-1);
  4. ListNode cursor = root;
  5. // 进位t
  6. int t = 0;
  7. while (l1 != null || l2 != null || t != 0) {
  8. if (l1 != null) {
  9. t += l1.val;
  10. l1 = l1.next;
  11. }
  12. if (l2 != null) {
  13. t += l2.val;
  14. l2 = l2.next;
  15. }
  16. cursor.next = new ListNode(t % 10);
  17. cursor = cursor.next;
  18. t /= 10;
  19. }
  20. return root.next;
  21. }
  22. }