题目描述

ED9125E2-8D19-4623-8687-B2BD5D4EC1B3_1_201_a.jpeg

题目链接

https://leetcode.cn/problems/add-two-numbers/

思路

由于输入的两个链表都是逆序存储数字的位数的,因此两个链表中同一位置的数字可以直接相加。

我们同时遍历两个链表,逐位计算它们的和,并与当前位置的进位值相加。具体而言,如果当前两个链表处相应位置的数字为【2】两数相加 - 图2,进位值为【2】两数相加 - 图3,则它们的和为【2】两数相加 - 图4;其中,答案链表处相应位置的数字为【2】两数相加 - 图5,而新的进位值为【2】两数相加 - 图6

如果两个链表的长度不同,则可以认为长度短的链表的后面有若干个 0,继续进行相加。此外,如果链表遍历结束后,有【2】两数相加 - 图7,还需要在答案链表的后面附加一个节点,节点的值为当前的【2】两数相加 - 图8

代码实现

  1. public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
  2. // 表示当前是否需要进位
  3. int carry = 0;
  4. ListNode h1 = l1, h2 = l2;
  5. ListNode res = new ListNode(0);
  6. ListNode cur = res;
  7. while (h1 != null || h2 != null) {
  8. int v1 = h1 == null ? 0 : h1.val;
  9. int v2 = h2 == null ? 0 : h2.val;
  10. // 计算总和
  11. int sum = v1 + v2 + carry;
  12. // 判断是否进位
  13. carry = sum / 10;
  14. // 添加当前节点元素
  15. cur.next = new ListNode(sum % 10);
  16. cur = cur.next;
  17. if (h1 != null) {
  18. h1 = h1.next;
  19. }
  20. if (h2 != null) {
  21. h2 = h2.next;
  22. }
  23. }
  24. // 最后看是否需要向前补一位
  25. if (carry > 0) {
  26. cur.next = new ListNode(carry);
  27. }
  28. return res.next;
  29. }

复杂度分析

  • 时间复杂度:【2】两数相加 - 图9,其中【2】两数相加 - 图10【2】两数相加 - 图11分别为两个链表的长度。我们要遍历两个链表的全部位置,而处理每个位置只需要【2】两数相加 - 图12的时间。
  • 空间复杂度:【2】两数相加 - 图13。注意返回值不计入空间复杂度。