🚩传送门:牛客题目
力扣题目

题1:链表相加 I

题目

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

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

数据范围:🍗[NC]317. 链表相加合集 - 图1

示例 1:
🍗[NC]317. 链表相加合集 - 图2

输入: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]


时间复杂度

时间复杂度:🍗[NC]317. 链表相加合集 - 图3,其中 🍗[NC]317. 链表相加合集 - 图4🍗[NC]317. 链表相加合集 - 图5 是链表的长度。

空间复杂度:🍗[NC]317. 链表相加合集 - 图6

我的代码

  1. public ListNode ListAdd (ListNode l1, ListNode l2) {
  2. // write code here
  3. int sum=0;
  4. int carry=0;
  5. int l1val=0;
  6. int l2val=0;
  7. ListNode head=new ListNode(0);
  8. ListNode tail=head;
  9. ListNode pl1=l1;
  10. ListNode pl2=l2;
  11. while(pl1!=null && pl2!=null){
  12. sum=pl1.val+pl2.val+carry; // 求和
  13. carry=sum/10; // 求进位
  14. tail.next=new ListNode(sum%10); // 分配新结点,赋值
  15. tail=tail.next; // 尾指针指向新结点
  16. pl1=pl1.next; // 哨兵下行
  17. pl2=pl2.next; // 哨兵下行
  18. }
  19. while(pl1!=null){ // pl1不空
  20. sum=carry+pl1.val; // 求和
  21. carry=sum/10; // 求进位
  22. tail.next=new ListNode(sum%10); // 分配新结点,赋值
  23. pl1=pl1.next; // 哨兵下行
  24. tail=tail.next; // 尾指针指向新结点
  25. }
  26. while(pl2!=null){ // pl2不空
  27. sum=carry+pl2.val; // 求和
  28. carry=sum/10; // 求进位
  29. tail.next=new ListNode(sum%10); // 分配新结点,赋值
  30. pl2=pl2.next; // 哨兵下行
  31. tail=tail.next; // 尾指针指向新结点
  32. }
  33. if(carry!=0){ // pl2和pl1同时空,但是进位仍在
  34. tail.next=new ListNode(carry); // 分配新结点,赋值进位
  35. tail=tail.next; // 尾指针指向新结点
  36. }
  37. tail.next=null; // 将尾巴的下一个指针指向null
  38. return head.next; // 返回头结点后的第一个结点
  39. }
  40. }

题2:链表相加 II

🚩传送门:牛客题目
力扣题目

题目

给定两个 非空 链表 l1l2 来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。

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

数据范围:🍗[NC]317. 链表相加合集 - 图7

示例1:
🍗[NC]317. 链表相加合集 - 图8

输入:l1 = [7,2,4,3], l2 = [5,6,4] 输出:[7,8,0,7]

时间复杂度

时间复杂度:🍗[NC]317. 链表相加合集 - 图9,其中 🍗[NC]317. 链表相加合集 - 图10🍗[NC]317. 链表相加合集 - 图11 是链表的长度。

空间复杂度:🍗[NC]317. 链表相加合集 - 图12

我的代码

  1. public class Solution {
  2. // 翻转链表
  3. public ListNode reverse(ListNode head){
  4. if(head==null||head.next==null) return head;
  5. ListNode pre=head;
  6. ListNode cur=head.next;
  7. ListNode next=null;
  8. pre.next=null;
  9. while(cur!=null){
  10. next=cur.next;
  11. cur.next=pre;
  12. pre=cur;
  13. cur=next;
  14. }
  15. return pre;
  16. }
  17. // 链表相加
  18. public ListNode addInList (ListNode head1, ListNode head2) {
  19. // write code here
  20. head1=reverse(head1); // 反转
  21. head2=reverse(head2); // 反转
  22. return reverse(ListAdd(head1,head2)); // 相加反转
  23. }
  24. public ListNode ListAdd (ListNode l1, ListNode l2) {
  25. // write code here
  26. int sum=0;
  27. int carry=0;
  28. int l1val=0;
  29. int l2val=0;
  30. ListNode head=new ListNode(0);
  31. ListNode tail=head;
  32. ListNode pl1=l1;
  33. ListNode pl2=l2;
  34. while(pl1!=null && pl2!=null){
  35. sum=pl1.val+pl2.val+carry; // 求和
  36. carry=sum/10; // 求进位
  37. tail.next=new ListNode(sum%10); // 分配新结点,赋值
  38. tail=tail.next; // 尾指针指向新结点
  39. pl1=pl1.next; // 哨兵下行
  40. pl2=pl2.next; // 哨兵下行
  41. }
  42. while(pl1!=null){ // pl1不空
  43. sum=carry+pl1.val; // 求和
  44. carry=sum/10; // 求进位
  45. tail.next=new ListNode(sum%10); // 分配新结点,赋值
  46. pl1=pl1.next; // 哨兵下行
  47. tail=tail.next; // 尾指针指向新结点
  48. }
  49. while(pl2!=null){ // pl2不空
  50. sum=carry+pl2.val; // 求和
  51. carry=sum/10; // 求进位
  52. tail.next=new ListNode(sum%10); // 分配新结点,赋值
  53. pl2=pl2.next; // 哨兵下行
  54. tail=tail.next; // 尾指针指向新结点
  55. }
  56. if(carry!=0){ // pl2和pl1同时空,但是进位仍在
  57. tail.next=new ListNode(carry); // 分配新结点,赋值进位
  58. tail=tail.next; // 尾指针指向新结点
  59. }
  60. tail.next=null; // 将尾巴的下一个指针指向null
  61. return head.next; // 返回头结点后的第一个结点
  62. }
  63. }