【链表专题】字节真题:单链表相加

本问题对应课程链接:剑指offer刷题第七期

要求:

1、请打卡你的解题代码,如果能简单说一下思路则简单说一下思路。
2、给出你代码所用的时间复杂度和空间复杂度

代码参考

// 注意,关于链表节点的定义(ListNode),我这里没有给出来哦
class SolutionAdd {
    // 反转链表
    public ListNode  reverseList(ListNode node){
        ListNode pre = null;
        ListNode q= null;
        while (node != null) {
            q= node.next;
            node.next = pre;
            pre = node;
            node = q;
        }
        return pre;
    }
    // 单链表相加
    public ListNode  addTwoNumbers(ListNode head1, ListNode head2) {
        // 虚拟头节点
        ListNode listNode = new ListNode(0);
        ListNode p = listNode;
        // sum 用来存放进位
        int sum = 0;
        while (head1 != null || head2 != null || sum!=0) {
            if (head1 != null) {
                sum += head1.val;
                head1 = head1.next;
            }

            if (head2 != null) {
                sum += head2.val;
                head2 = head2.next;
            }
            p.next = new ListNode(sum % 10);
            sum = sum / 10;
            p = p.next;
        }
        return listNode.next;
    }
}

时间复杂度:O(n+m)
空间复杂度:O(1)

共以下 32 个回答

  • 為愛而生 普通 2025年3月24日 下午9:39

    class Solution {
    // 两数相加Ⅱ
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {

        Deque <Integer> stack1 = new ArrayDeque<Integer>();
        Deque <Integer> stack2 = new ArrayDeque<Integer>();
        while (l1 != null) {
            stack1.push(l1.val);
            l1 = l1.next;
        }
        while (l2 != null) {
            stack2.push(l2.val);
            l2 = l2.next;
        }
        int carry = 0;
        ListNode ans = null;
        while (!stack1.isEmpty() || !stack2.isEmpty() || carry != 0) {
            int a = stack1.isEmpty() ? 0 : stack1.pop();
            int b = stack1.isEmpty() ? 0 : stack2.pop();
            int cur = a + b + carry;
            carry = cur / 10;
            cur %= 10;
            ListNode curnode = new ListNode(cur);
            curnode.next = ans;
            ans = curnode;
        }
        return ans;
    }
    
    0 赞同 0 条回复
  • 桃桃摇摇奶昔° 普通 2024年12月19日 上午11:10
    Class Solution {
            //反转链表
        public ListNode reverse(ListNode node){
            ListNode pre=null;
            ListNode q=null;
            while(node!=null){
                q=node.next;//保存后面的节点
                node.next=pre;
                pre=node;
                node=q;
            }
            return pre;
        }
        public ListNode add(ListNode head1,ListNode head2){
            ListNode listnode=new listnode(0);
            ListNode p=listnode;
            int sum=0;
            while (head1!=null || head2 != null || sum!=0){
                  if (head1!=null){
                        sum+=head1.val;
                        head1=head1.next
                        }
                 if (head1!=null){
                       sum+=head1.val;
                       head1=head1.next
                       }
                  p.next=new ListNode(sum%10);
                  sum=sum/10;
                  p=p.next
                  }
                return listnode.next;
        }
    }
    
    0 赞同 0 条回复
  • Lil Lee_ 普通 2024年12月1日 下午8:16
    //模拟
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            ListNode head = null, tail = null;
            int carry = 0;
            while(l1 != null || l2 != null){
                int n1 = l1 != null ? l1.val : 0;
                int n2 = l2 != null ? l2.val : 0;
                int sum = n1 + n2 + carry;
                if(head == null){
                    head = tail = new ListNode(sum % 10);
                }else{
                    tail.next = new ListNode(sum % 10);
                    tail = tail.next;
                }
                carry = sum / 10;
                if(l1 != null){
                    l1= l1.next;
                }
                if(l2 != null){
                    l2= l2.next;
                }
            }
            if(carry > 0){
                tail.next = new ListNode(carry);
            }
            return head;
        }
    }
    
    0 赞同 0 条回复
  • mpweixin用户 普通 2024年11月30日 下午6:31

    先将两个链表翻转,然后相加,最后在翻转

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, val=0, next=None):
    #         self.val = val
    #         self.next = next
    class Solution:
        def recur(self, cur, pre):
            if not cur:
                return pre
            res = self.recur(cur.next, cur)
            cur.next = pre
            return res
    
        def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
            copied_l1 = self.recur(l1, None)
            copied_l2 = self.recur(l2, None)
            res = ListNode(0)
            carry = 0
            cur = res
            while copied_l1 or copied_l2:
                x = copied_l1.val if copied_l1 else 0
                y = copied_l2.val if copied_l2 else 0
                cur.next = ListNode((x + y + carry) % 10)
                carry = (x + y + carry) // 10
                cur = cur.next
                if copied_l1:
                    copied_l1 = copied_l1.next
                if copied_l2:
                    copied_l2 = copied_l2.next
            if carry:
                cur.next = ListNode(carry)
            result = self.recur(res.next, None)
            return result
    
    0 赞同 0 条回复
  • YULONG 永久会员 2024年11月30日 上午2:22
    # 反转两链表,相加之后在反转回来,时间复杂度O(N)
    #
    class Solution:
        def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
    
            l1, _ = self.reverse(l1, None)
            l2, _ = self.reverse(l2, None)
    
            dummy = nhead = ListNode()
            add = 0
            while l1 or l2:
                if l1 and l2:
                    s = l1.val + l2.val + add 
                    add = s // 10
                    val = s % 10
                    l1 = l1.next
                    l2 = l2.next
                elif l1:
                    s = l1.val + add 
                    add = s // 10
                    val = s % 10
                    l1 = l1.next
                else:
                    s = l2.val + add 
                    add = s // 10
                    val = s % 10
                    l2 = l2.next
    
                nhead.next = ListNode(val)
                nhead = nhead.next
    
            if add:
                nhead.next = ListNode(add)
                nhead = nhead.next
    
            ans, _ = self.reverse(dummy.next, None)
            return ans 
    
    
    
    
        def reverse(self, node, tail):
            pre = None
            cur = node
            while cur != tail:
                tmp = cur.next
                cur.next = pre
                pre = cur
                cur = tmp
            return pre, node
    
    
    0 赞同 0 条回复
  • 岱 永久会员 2024年11月28日 下午8:46
    1. leetcode地址https://leetcode.cn/problems/lMSNwu/
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            ListNode head1 = reverse(l1);
            ListNode head2 = reverse(l2);
            ListNode re = add(head1,head2);
            re = reverse(re);
            return re;
        }
    
        private ListNode reverse(ListNode head){
            if( head == null) return null;
            ListNode cur = head, pre = null;
            while(cur != null){
                ListNode t = cur.next;
                cur.next = pre;
                pre = cur;
                cur = t;
            }
            return pre;
        }
    
        private ListNode add(ListNode head1,ListNode head2){
            // 虚拟头节点
            ListNode ans = new ListNode(0);
            ListNode p = ans;
            // sum 用来存放进位
            int sum = 0;
            while (head1 != null || head2 != null || sum!=0) {
                if (head1 != null) {
                    sum += head1.val;
                    head1 = head1.next;
                }
    
                if (head2 != null) {
                    sum += head2.val;
                    head2 = head2.next;
                }
                p.next = new ListNode(sum % 10);
                sum = sum / 10;
                p = p.next;
            }
            return ans.next;
        }
    
    
    }
    
    0 赞同 0 条回复
  • yelinliner 普通 2024年11月28日 下午3:30

    反转+合并

    class Solution {
        public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            // 反转
            l1 = reverseList(l1);
            l2 = reverseList(l2);
            // 相加后返回的新链表 辅助节点
            ListNode merge = new ListNode(0);
            ListNode temp = merge;
            // 存储进位
            int sum = 0;
            while (l1 != null || l2 != null || sum != 0) {
                if (l1 != null) {
                    sum += l1.val;
                    l1 = l1.next;
                }
                if (l2 != null) {
                    sum += l2.val;
                    l2 = l2.next;
                }
                // 余数
                temp.next = new ListNode(sum % 10);
                // 保存进位
                sum = sum / 10;
                temp = temp.next;
            }
            // 再次反转
            return reverseList(merge.next);
        }
    
        /**
         * 反转列表
         */
        public ListNode reverseList(ListNode head) {
            // 临界判断
            if (head == null || head.next == null) {
                return head;
            }
            // 反转
            ListNode cur = head;
            ListNode pre = null;
            while (cur != null) {
                ListNode temp = cur.next;
                cur.next = pre;
                pre = cur;
                cur = temp;
            }
            return pre;
        }
    }
    
    0 赞同 0 条回复
  • 陆狗陆狗 普通 2024年11月26日 下午11:44
    public class ListAddTest {
        public static void main(String[] args) {
            ListNode head = ListNodeUtil.of(1, 2, 3, 4);
            ListNode head2 = ListNodeUtil.of(6, 7);
            ListNodeUtil.print(head);
            ListNodeUtil.print(head2);
            // 各自进行反转
            ListNode reverse = reverse(head);
            ListNode reverse2 = reverse(head2);
            // 链表相加并进位
            ListNode addList = new ListNode(0);
            ListNode tempt=addList;
            int overNumber = 0;
            while (reverse != null || reverse2 != null || overNumber != 0) {
                // 相加并进位(余数是新节点,商进位)
                int val1 = reverse != null ? reverse.val : 0;
                int val2 = reverse2 != null ? reverse2.val : 0;
                int sumVal = val1 + val2 + overNumber;
                int val = sumVal % 10;
                tempt.next = new ListNode(val);
                overNumber = sumVal / 10;
                // 游标进位
                if (reverse != null) {
                    reverse = reverse.next;
                }
                if (reverse2 != null) {
                    reverse2 = reverse2.next;
                }
                tempt=tempt.next;
            }
            // 相加后的结果进行翻转
            ListNode result = reverse(addList.next);
            ListNodeUtil.print(result);
    
        }
    
        /**
         * 原地反转链表
         *
         * @param head
         * @return
         */
        public static ListNode reverse(ListNode head) {
            if (head == null || head.next == null) {
                return head;
            }
            // 剩余部分先进行反转
            ListNode otherReverse = reverse(head.next);
            // 剩余部分的尾节点指向头结点
            head.next.next = head;
            // 原头结点指向null,防止成环
            head.next = null;
            return otherReverse;
    
        }
    }
    

    打印结果
    打印开始———————-》
    1 -> 2 -> 3 -> 4
    打印结束———————-》
    打印开始———————-》
    6 -> 7
    打印结束———————-》
    打印开始———————-》
    1 -> 3 -> 0 -> 1
    打印结束———————-》

    0 赞同 1 条回复
    • 陆狗陆狗 普通 @ 陆狗陆狗 2024年11月27日 上午9:28

      提供下我写的工具类和ListNode的定义

      public class ListNode {
      
          public int val;
          public ListNode next;
      
          public ListNode() {}
      
          public ListNode(int val) {
              this.val = val;
          }
      
          public ListNode(int val, ListNode next) {
              this.val = val;
              this.next = next;
          }
      }
      
      public class ListNodeUtil {
      
          public static ListNode of(Integer... values) {
              ListNode head = new ListNode(0);
              ListNode tmpt=head;
              for (Integer value : values) {
                  tmpt.next = new ListNode(value);
                  tmpt = tmpt.next;
              }
              return head.next;
          }
      
          public static void print(ListNode head) {
              System.out.println("打印开始----------------------》");
              StringBuilder stringBuilder=new StringBuilder();
              while (head != null) {
                  if (StrUtil.isNotBlank(stringBuilder)){
                      stringBuilder.append(" -> ");
                  }
                  stringBuilder.append(head.val);
                  head = head.next;
              }
              System.out.println(stringBuilder);
              System.out.println("打印结束----------------------》");
          }
      }
      
  • hjx 普通 2024年11月26日 下午8:03

    // 注意,关于链表节点的定义(ListNode),我这里没有给出来哦
    class SolutionAdd {
    // 反转链表
    public ListNode reverseList(ListNode node){
    ListNode pre = null;
    ListNode q= null;
    while (node != null) {
    q= node.next;
    node.next = pre;
    pre = node;
    node = q;
    }
    return pre;
    }
    // 单链表相加
    public ListNode addTwoNumbers(ListNode head1, ListNode head2) {
    // 虚拟头节点
    ListNode listNode = new ListNode(0);
    ListNode p = listNode;
    // sum 用来存放进位
    int sum = 0;
    while (head1 != null || head2 != null || sum!=0) {
    if (head1 != null) {
    sum += head1.val;
    head1 = head1.next;
    }

            if (head2 != null) {
                sum += head2.val;
                head2 = head2.next;
            }
            p.next = new ListNode(sum % 10);
            sum = sum / 10;
            p = p.next;
        }
        return listNode.next;
    }
    

    }

    0 赞同 0 条回复
  • Aatorx 永久会员 2024年11月25日 下午3:38
    class Solution {
    public:
    /* 反转链表
    ListNode* reverse(ListNode* head){
    ListNode* pre = Null;
    ListNode* cur = Null;
    while(head != Null){
    cur = head->next;
    head->next = pre;
    pre = head;
    head = cur;
    }
    return pre;
    }
    /*链表相加
    ListNode* add(ListNode* a, ListNode* b){
    ListNode* res = new ListNode(0)
    ListNode* temp = res;
    /* 记录是否进位
    bool carry = False;
    a = reverse(a);
    b = reverse(b);
    /* 先处理两个链表公共相加部分
    while(a != Null && b != Null){
    if (carry){
    int sum = a->val + b->val + 1;
    }else{
    int sum = a->val + b->val;
    }
    temp->next = new ListNode(sum%10);
    temp = temp->next;
    a = a->next;
    b = b->next;
    if(sum>=10){
    carry = True;
    }else{
    carry = False;
    }
    }
    /* 处理链表剩余部分
    while(a != Null && b != Null){
    if (a!= Null){
    if (carry){
    int sum = a->val + 1;
    }else{
    int sum = a->val;
    }
    temp->next = new ListNode(sum%10);
    temp = temp->next;
    a = a->next;
    if(sum>=10){
    carry = True;
    }else{
    carry = False;
    }
    }
    if (b!= Null){
    if (carry){
    int sum = b->val + 1;
    }else{
    int sum = b->val;
    }
    temp->next = new ListNode(sum%10);
    temp = temp->next;
    b = b->next;
    if(sum>=10){
    carry = True;
    }else{
    carry = False;
    }
    }
    return reverse(res->next);
    }
    };
    

    时间复杂度O(m+n)
    空间复杂度O(max(m+n))

    0 赞同 0 条回复
  • 张君雅小妹妹 普通 2024年11月24日 下午9:39
        public static ListNode sumList(ListNode head1, ListNode head2){
            if(head1 == null) return head1;
            if(head2 == null) return head2;
            ListNode head1_new = reverse(head1);
            ListNode head2_new = reverse(head2);
            ListNode res = new ListNode(0);  // 前置节点
            ListNode cur = res;
            int carry = 0;
            int sum = 0;
            while(head1_new != null || head2_new != null){
                if(head1_new != null){
                    sum += head1_new.val;
                    head1_new = head1_new.next;
                }
    
                if(head2_new != null){
                    sum += head2_new.val;
                    head2_new = head2_new.next;
                }
    
                sum += carry;
                cur.next = new ListNode(sum % 10);
                cur = cur.next;
                carry = sum / 10;
                sum = 0;
            }
    
            return reverse(res.next);
    
        }
    
    
        public static ListNode reverse(ListNode head){
            if(head == null || head.next == null) return head;
            ListNode prev = null;
            ListNode cur = head;
            ListNode aft;
            while(cur != null){
                aft = cur.next;
                cur.next = prev;
                prev = cur;
                cur = aft;
            }
            printListNode(prev);
            return prev;
        }
    

    sum这块的写法可以更简单一点,不需要carry。定义一个前置节点能省去很多判断!
    时间复杂度O(max(m,n))
    空间复杂度O(1)

    0 赞同 0 条回复
  • Pendulumpal 普通 2024年11月24日 下午7:17

    时间复杂度:O(n)
    空间复杂度:O(m+n)

    “`c++
    ListNode* filp(ListNode* head){
    if(!head)return nullptr;
    if(!(head->next))return head;
    ListNode* res=filp(head->next);
    head->next->next=head;
    head->next=nullptr;
    return res;
    }
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    l1=filp(l1);
    l2=filp(l2);
    ListNode* res=new ListNode(-1,nullptr);
    ListNode* p=res;
    int cur=0;
    int pre=0;
    while(l1||l2||pre){
    if(!l1&&l2){
    cur=(l2->val+pre)%10;
    p->next=new ListNode(cur);
    pre=(l2->val+pre)/10;
    l2=l2->next;
    }else if(!l2&&l1){
    cur=(l1->val+pre)%10;
    p->next=new ListNode(cur);
    pre=(l1->val+pre)/10;
    l1=l1->next;
    }else if(!l1&&!l2){
    cur=pre%10;
    p->next=new ListNode(pre);
    pre=pre/10;
    }else{
    cur=(l1->val+l2->val+pre)%10;
    p->next=new ListNode(cur);
    pre=(l1->val+l2->val+pre)/10;
    l1=l1->next;
    l2=l2->next;
    }
    p=p->next;
    }
    return filp(res->next);
    }
    “`

    0 赞同 0 条回复
  • 无言 永久会员 2024年11月24日 下午3:43
    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        ListNode* reverseListNode(ListNode* head) {
            ListNode* newHead = nullptr;
            ListNode* cur = head;
            while (cur) {
                ListNode* temp = cur->next;
                cur->next = newHead;
                newHead = cur;
                cur = temp;
            }
            return newHead;
        }
        ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
            //反转原来的两个链表
            ListNode* newHead1 = reverseListNode(l1);
            ListNode* newHead2 = reverseListNode(l2);
    
            ListNode* dummy = new ListNode();
            ListNode* cur = dummy;
            int carry = 0; //存储进位
            while (newHead1 != nullptr || newHead2 != nullptr || carry != 0) {
                int sum = 0;
                if (newHead1 != nullptr) {
                    sum += newHead1->val;
                    newHead1 = newHead1->next;
                }
                if (newHead2 != nullptr) {
                    sum += newHead2->val;
                    newHead2 = newHead2->next;
                }
                sum += carry;
                cur->next = new ListNode(sum % 10);
                carry = sum / 10;
                cur = cur->next;
            }
            //反转结果链表
            cur = dummy->next;
            dummy->next = nullptr;
            ListNode* newHead3 = reverseListNode(cur); 
            return newHead3;
        }
    };
    时间复杂度: O(max(M,N))
    空间复杂度: O(M+N)
    
    0 赞同 0 条回复
  • Poetry and distance 永久会员 2024年11月23日 下午8:55
    思路:首先进行反转,接着从前往后依次相加,特别注意,进为的1节点也要重新new一个新节点
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public ListNode reverse(ListNode head){
            if(head==null || head.next==null){
                return head;
            }
            ListNode pre=null;
            while(head!=null){
                ListNode temp=head.next;
                head.next=pre;
                pre=head;
                head=temp;
            }
            return pre;
        }
        public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            l1=reverse(l1);
            l2=reverse(l2);
            int sum=0;
            ListNode sumRes=new ListNode(-1);
            ListNode p=sumRes;
            ListNode p1=l1,p2=l2;
            while(p1!=null || p2!=null || sum!=0){
                if(p1!=null){
                    sum=sum+p1.val;
                    p1=p1.next;
                }
                if(p2!=null){
                    sum=sum+p2.val;
                    p2=p2.next;
                }
                p.next=new ListNode(sum%10);
                sum=sum/10;
                p=p.next;
            }
            return sumRes.next;
        }
    }
    时间复杂度:O(max(m,n))
    空间复杂度:O(1)
    
    0 赞同 0 条回复
  • Renasc 普通 2024年11月23日 下午7:58
    public class Solution {
        /**
         * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
         *
         * 
         * @param head1 ListNode类 
         * @param head2 ListNode类 
         * @return ListNode类
         */
        public ListNode addInList (ListNode head1, ListNode head2) {
            ListNode dummy = new ListNode(0);
            ListNode curr = dummy;
            int carry=0;
    
            // 翻转两个链表
            ListNode l1 = reverstList(head1);
            ListNode l2 = reverstList(head2);
    
            while (l1 != null || l2 != null || carry != 0) {
                int sum = carry;
    
                if (l1 != null) {
                    sum += l1.val;
                    l1 = l1.next;
                }
    
                if (l2 != null) {
                    sum += l2.val;
                    l2 = l2.next;
                }
    
                carry = sum / 10;
                int digit = sum % 10;
    
                curr.next = new ListNode(digit);
                curr = curr.next;
            }
    
            ListNode res = reverstList(dummy.next);
    
            return res;
        }
    
        public ListNode reverstList(ListNode head) {
            if (head == null) {
                return head;
            }
            ListNode prev = null;
            ListNode curr = head;
    
            while (curr != null) {
                ListNode nextNode = curr.next;
                curr.next = prev;
                prev = curr;
                curr = nextNode;
            }
    
            return prev;
        }
    }
    
    0 赞同 0 条回复
  • 生活在经验里 普通 2024年11月23日 下午4:41
    // 思路:先把2个链表进行反转,相加之后,得到结果,再把结果进行反转
    func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
        l1 = reverseList(l1)
        l2 = reverseList(l2)
        sum := 0
        carry := 0
        var head, tmp *ListNode
        for l1!=nil || l2!=nil || carry!=0{
            if tmp==nil{
                head = new(ListNode)
                tmp = head
            }else{
                tmp.Next=&ListNode{}
                tmp = tmp.Next
            }
    
            n1 := 0
            n2 := 0
            if l1 != nil{
                n1 = l1.Val
                l1 = l1.Next
            }
            if l2 != nil{
                n2 = l2.Val
                l2 = l2.Next
            }
            sum = (n1 + n2 + carry) % 10
            carry = (n1 + n2 + carry) / 10
            tmp.Val = sum
        }
        return reverseList(head)
    }
    
    func reverseList(head *ListNode) *ListNode {
        if head == nil || head.Next == nil {
            return head
        }
        newHead := reverseList(head.Next)
        node := head.Next
        node.Next = head
        head.Next = nil
        return newHead
    }
    
    0 赞同 0 条回复
  • Xiang. 永久会员 2024年11月23日 下午3:12
    
    class ListNode {
        int val;
        ListNode next;
        ListNode() {}
        ListNode(int val) { this.val = val; }
        ListNode(int val, ListNode next) { this.val = val; this.next = next; }
    }
    时间复杂度O(n)
    空间复杂度O(n)
    public class Main {
        public static void main(String[] args) {
            //通过反转链表实现两个正整数的和。
            ListNode head1=new ListNode(1,new ListNode(2,new ListNode(3,new ListNode(4,null))));
            ListNode head2=new ListNode(3,new ListNode(4,null));
    
            ListNode newHead1=Main.reverse_1(head1);
            ListNode newHead2=Main.reverse_2(head2,null);
    
            ListNode t1=newHead1;
            ListNode t2=newHead2;
    
            ListNode head3=new ListNode(-1);
            ListNode t3=head3;
            while(t1!=null&&t2!=null){
                ListNode newTmp=new ListNode(t1.val+t2.val);
                t3.next=newTmp;
                t1=t1.next;
                t2=t2.next;
                t3=t3.next;
            }
            if(t1==null) t3.next=t2;
            else t3.next=t1;
    
            t3=head3.next;
            while (t3.next!=null){
                if(t3.val>=10){
                    t3.val-=10;
                    t3.next.val+=1;
                }
                t3=t3.next;
            }
            if(t3.val>10){
                ListNode n=new ListNode(1,null);
                t3.val-=10;
                t3.next=n;
            }
            ListNode head = reverse_2(head3.next,null);
            t3=head;
            while(t3!=null){
                System.out.println(t3.val);
                t3=t3.next;
            }
        }
    
        //反转链表的递归和迭代的实现:
        public static ListNode reverse_1(ListNode head){
            ListNode pre=null;
            ListNode cur=head;
            ListNode tmp;
            while(cur!=null){
                tmp=cur.next;
                cur.next=pre;
                pre=cur;
                cur=tmp;
            }
            return pre;
        }
        public static ListNode reverse_2(ListNode cur,ListNode pre){
            if(cur==null) return pre;
            ListNode tmp=cur.next;
            cur.next=pre;
            return reverse_2(tmp,cur);
        }
    }
    
    
    0 赞同 0 条回复
  • Firefly 普通 2024年11月23日 下午2:59

    /**
    * Definition for singly-linked list.
    * struct ListNode {
    * int val;
    * ListNode next;
    * ListNode() : val(0), next(nullptr) {}
    * ListNode(int x) : val(x), next(nullptr) {}
    * ListNode(int x, ListNode *next) : val(x), next(next) {}
    * };
    */
    class Solution {
    public:
    ListNode
    addTwoNumbers(ListNode* l1, ListNode* l2) {
    ListNode *pHead=nullptr;
    auto p1=l1,p1Cur=l1,p2=l2,p2Cur=l2;
    while(p1!=nullptr&&p2!=nullptr)
    {
    p1=p1->next;
    p2=p2->next;
    }

        while(p1!=nullptr)
        {
            pHead=new ListNode(p1Cur->val,pHead);
            p1Cur=p1Cur->next;
            p1=p1->next;
        }
    
        while(p2!=nullptr)
        {
            pHead=new ListNode(p2Cur->val,pHead);
            p2Cur=p2Cur->next;
            p2=p2->next;
        }
    
        while(p1Cur!=nullptr&&p2Cur!=nullptr)
        {
            pHead=new ListNode(p1Cur->val+p2Cur->val,pHead);          
            p1Cur=p1Cur->next;
            p2Cur=p2Cur->next;
        }
    
        ListNode *pHead2=nullptr;
        int nCarry=0;
        for(auto k=pHead;k!=nullptr;)
        {
            k->val+=nCarry;
            nCarry=k->val/10;
            k->val%=10;
            auto pTmp=k->next;
            k->next=pHead2;
            pHead2=k;
            k=pTmp;
        }
    
        pHead=pHead2;
        if(nCarry>0)
        {
            pHead=new ListNode(nCarry,pHead);
        }
        return pHead;
    }
    

    };
    执行时间超过6.9%的提交用户

    0 赞同 0 条回复
  • 月下足迹 普通 2024年11月23日 下午1:49

    public class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }
    }

    public ListNode reverseList(ListNode head) {
        if(head == null) {
            return head;
        }
    
        ListNode p1 = new ListNode(-1);
        ListNode cur = head;
        ListNode nextListNode = head;
    
        //头插法倒序
        while (cur != null) {
            nextListNode = cur.next;
            cur.next = p1.next;
            p1.next = cur;
            cur = nextListNode;
        }
        head = p1.next;
        p1.next = null;
        return head;
    }
    
    public ListNode  addTwoNumbers(ListNode head1, ListNode head2) {
        // 虚拟头节点
        ListNode listNode = new ListNode(0);
        ListNode p = listNode;
        //sum存放进位
        int sum = 0;
        while (head1 != null || head2!=null || sum != 0) {
            if(head1 != null ) {
                sum += head1.val;
                head1 = head1.next;
            }
    
            if(head2 != null ) {
                sum += head2.val;
                head2 = head2.next;
            }
    
            ListNode newNode = new ListNode(sum % 10);
            p.next = newNode;
            sum/=10;
            p = p.next;
    
        }
    
        return listNode.next;
    }
    
    0 赞同 0 条回复
  • Kisara 普通 2024年11月23日 下午12:41

    ““java

    // 注意,关于链表节点的定义(ListNode),我这里没有给出来哦
    class SolutionAdd {
    // 反转链表
    public ListNode reverseList(ListNode node){
    ListNode pre = null;
    ListNode q= null;
    while (node != null) {
    q= node.next;
    node.next = pre;
    pre = node;
    node = q;
    }
    return pre;
    }
    // 单链表相加
    public ListNode addTwoNumbers(ListNode head1, ListNode head2) {
    l1=reverseList(head1);
    l2=reverseList(head2);
    // 虚拟头节点
    ListNode listNode = new ListNode(0);
    ListNode p = listNode;
    // sum 用来存放进位
    int sum = 0;
    while (l1!= null || l2!= null || sum!=0) {
    if (l1!= null) {
    sum += l1.val;
    l1= l1.next;
    }

            if (l2!= null) {
                sum += l2.val;
                l2= l2.next;
            }
            p.next = new ListNode(sum % 10);
            sum = sum / 10;
            p = p.next;
        }
        return reverseList(listNode.next);
    }
    
    0 赞同 0 条回复
  • momo 普通 2024年11月23日 上午11:13

    class ListNode:
    def init(self, val=0, next=None):
    self.val = val
    self.next = next

    class Solution:
    def resverse(self, head):
    temp = None
    cur = head
    while cur:
    nxt = cur.next
    cur.next = temp
    temp = cur
    cur = nxt
    return temp
    def adding(self, headA, headB):
    curA = headA
    curB = headB
    carry = 0
    dummy = ListNode(1)
    cur = dummy
    while(curA and curB):
    number = (curA.val + curB.val + carry) % 10
    carry = (curA.val + curB.val + carry) // 10
    cur.next = ListNode(number)
    cur = cur.next
    curA = curA.next
    curB = curB.next
    if curA: cur.next = curA
    elif curB: cur.next = curB

        return dummy.next
    

    反转+相加

    0 赞同 0 条回复
  • zing 普通 2024年11月23日 上午10:12

    先反转链表,相加得到结果后再反转

    class ListNode:
        def __init__(self, val=0, next=None):
            self.val = val
            self.next = next
    
    class Solution:
        def trainningPlan(self, head: ListNode) -> ListNode:
    #         反转链表
            if head is None or head.next is None: 
                return head
    
            node = self.trainningPlan(head.next)
            head.next.next = head
            head.next = None
    
            return node
    
        def addListNode(self, A: ListNode, B: ListNode) -> ListNode:
    #         两个链表相加
            sum = 0
            heada, headb = A, B
            ans = ListNode()
            newnode = ans
            while (heada != None or headb != None or sum != 0):
                if heada != None:
                    sum += head1.val;
                    heada = heada.next
    
                if headb != None:
                    sum += headb.val;
                    headb = headb.next
    
                newnode.next = ListNode(sum%10)
                sum /= 10
                newnode = newnode.next
    
            return ans.next
    
    0 赞同 0 条回复
  • jaron 普通 2024年11月23日 上午10:03

    测试连接:445. 两数相加 II – 力扣(LeetCode)

    时间复杂度:O(n+m)
    空间复杂度:O(1)

    class Solution {
        // 反转链表
        public ListNode reverse(ListNode head) {
            ListNode pre = null;
            ListNode cur = head;
            while (cur != null) {
                ListNode temp = cur.next;
                cur.next = pre;
                pre = cur;
                cur = temp;
            }
            return pre;
        }
    
        public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            l1 = reverse(l1);
            l2 = reverse(l2);
            // 虚拟头结点
            ListNode dummy = new ListNode(0);
            ListNode cur = dummy;
            int sum = 0;
            while (l1 != null || l2 != null || sum != 0) {
                if (l1 != null) {
                    sum += l1.val;
                    l1 = l1.next;
                }
                if (l2 != null) {
                    sum += l2.val;
                    l2 = l2.next;
                }
                cur.next = new ListNode(sum % 10);
                sum /= 10;
                cur = cur.next;
            }
            ListNode ans = reverse(dummy.next);
            return ans;
        }
    }
    
    0 赞同 0 条回复
  • Tom Yuan 普通 2024年11月23日 上午3:33

    思路:把两个链表转成数字 求和 然后把结果转成string以方便从开头开始取值 最后塞入新链表时把每一位转回int
    比较python的做法 放别的语言可能要复杂点 包括考虑一百位的数字的数据类型等等

    class Solution:
        def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
            num1 = self.llToNum(l1)
            num2 = self.llToNum(l2)
    
            num_sum = num1 + num2
            num_sum_str = str(num_sum)
            new_head = ListNode(0)
            temp = new_head
            for i in range(len(num_sum_str)):
                temp.next = ListNode(int(num_sum_str[i]))
                temp = temp.next
    
            return new_head.next
    
        def llToNum(self, head: ListNode):
            num = 0
            while head != None:
                num = num * 10 + head.val
                head = head.next
            return num
    

    time O(n) space O(m+n)取决于结果数字的长度

    0 赞同 0 条回复
  • mpweixin用户 普通 2024年11月22日 下午11:52

    思路:先翻转链表,逐位相加后,再把结果翻转。
    class Node {
    public:
    int val;
    Node* next;

    Node(int _val) {
        val = _val;
        next = NULL;
    }
    

    };

    class Solution{
    public:
    Node* f(Node* head){
    if(head NULL) return head;
    Node* pre = NULL;
    Node* cur = head;
    while(cur){
    Node* temp = cur;
    cur->next = pre;
    pre = cur;
    cur = temp->next;
    }
    return pre;
    }

    Node* addList(Node* l1, Node* l2){
        if(l1 == NULL && l2 != NULL) return l2;
        if(l2 == NULL && l1 != NULL) return l1;
        if(l1 == NULL && l2 == NULL) return NULL;
    
        Node* l1_r = f(l1);
        Node* l2_r = f(l2);
        Node* add_r = l1_r;
    
        while(l1_r&&l2_r){
            l1_r->val += l2_r->val;
            l1_r = l1_r->next;
            l2_r = l2_r->next; 
        }
    
        Node* result = add_r;
        while(add_r){
            if(add_r->next == NULL){
                if(l2_r){
                    add_r->next = l2_r;
                }
    
            if(add_r->val >= 10){
                if(add_r->next){
                    add_r->next->val += add_r->val / 10;
                }
                else{
                    add_r->next = New Node(add_r->val / 10);
                }
                add_r->val %= 10;
            }
            add_r = add_r->next;
        }
    
        return f(result);
    }
    

    };
    时间复杂度O(n+m),空间复杂度O(1)。

    0 赞同 0 条回复
  • 🌟 普通 2024年11月22日 下午11:12

    先反转链表,从个位开始,再返回原状;
    node* node_reserve(node* head){
    node* pre=NULL;
    node* cur=head;
    while(cur){
    node* next=cur->next;
    cur->next=pre;
    pre=cur;
    cur=next; // Move to the next node
    }
    return pre; // Return the value of the new head
    }

    int doublelist_add(node *head1, node *head2)
    {
    node *reserve_head1 = node_reserve(head1);
    node *reserve_head2 = node_reserve(head2);
    node *cur1 = reserve_head1;
    node *cur2 = reserve_head2;
    int carry = 0;
    int sum = 0;
    int bit = 0;
    int result = 0;
    while (cur1 || cur2 || carry)
    {
    bit = bit? bit * 10:1;
    int val1=cur1 ? cur1->val : 0;
    int val2=cur2 ? cur2->val : 0; // Get the value of the current node or 0 if at the end of the list
    sum = val1 + val2 + carry; // Calculate the sum of the current digits and the carry
    carry = sum / 10;
    sum %= 10;
    result += bit * sum; // Add the current digit to the result
    cout<<result<<endl; // Print the current result
    cur1 = cur1 ? cur1->next : nullptr;
    cur2 = cur2 ? cur2->next : nullptr; // Move to the next node in both lists or nullptr if at the end
    }

     head1 = node_reserve(reserve_head1);
     head2 = node_reserve(reserve_head2);
     return result; // Return the sum of the two numbers represented by the linked lists
    

    }

    int main(){
    node* head=new node(1);
    head->next=new node(2);
    head->next->next=new node(3);
    head->next->next->next=new node(4);

    node* head2=new node(6);
    head2->next=new node(7);
    head2->next->next=new node(8);
    

    doublelist_add(head,head2);
    // Clean up memory
    node* temp;
    while(head){
    temp=head;
    head=head->next;
    delete temp;
    }
    while(head2){
    temp=head2;
    head2=head2->next;
    delete temp;
    }
    return 0;
    }

    0 赞同 0 条回复
  • 休一 普通 2024年11月22日 下午10:19
    class Solution {
    public:
    //翻转链表
        ListNode* reverseList(ListNode* head)
        {
            if(head==nullptr) return nullptr;
            ListNode* pre = nullptr;
            ListNode* cur = head;
            while(cur)
            {
                ListNode* Next = cur->next;
                cur->next = pre;
    
                pre = cur;
                cur = Next;
            }
            return pre;
        }
        ListNode* addTwoNumbers(ListNode* l1, ListNode* l2)
        {
            ListNode* l1_new = reverseList(l1);
            ListNode* l2_new = reverseList(l2);
            return reverseList(addTwoNumbersWithCarry(l1_new,l2_new,0));
        }
        ListNode* addTwoNumbersWithCarry(ListNode* l1, ListNode* l2, int carry = 0) {
            if (!l1 && !l2 && carry == 0) return nullptr;  // 终止条件:两个链表为空且没有进位
    
            // 获取当前节点的值,如果为空则视为 0
            int val1 = l1 ? l1->val : 0;
            int val2 = l2 ? l2->val : 0;
    
            // 计算当前节点的和,以及进位
            int sum = val1 + val2 + carry;
            carry = sum / 10;  // 新的进位
            sum = sum % 10;    // 当前节点值
    
            // 创建新节点存储当前位结果
            ListNode* result = new ListNode(sum);
    
            // 递归处理下一位
            result->next = addTwoNumbersWithCarry(l1 ? l1->next : nullptr, l2 ? l2->next : nullptr, carry);
    
            return result;
        }
    };
    
    
    
    0 赞同 0 条回复
  • lQl 永久会员 2024年11月22日 下午10:11

    先反转,再相加,再反转
    时间复杂度O(m+n)
    空间复杂度O(m+n)
    递归反转+递归相加

    class Solution {
        public ListNode reverseListNode(ListNode l) {
            if (l == null || l.next == null) {
                return l;
            }
            ListNode cur = reverseListNode(l.next);
            l.next.next = l;
            l.next = null;
            return cur;
        }
    
        public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            // 反转链表
            ListNode l11 = reverseListNode(l1);
            ListNode l22 = reverseListNode(l2);
    
            // 相加
            ListNode cur = addHelper(l11,l22,0);
    
            return reverseListNode(cur);
    
        }
        public ListNode addHelper(ListNode l1,ListNode l2,int sum){
            if(l1==null&&l2==null&&sum==0){
                return null;
            }
            if(l1!=null){
                sum+=l1.val;
                l1=l1.next;
            }
            if(l2!=null){
                sum+=l2.val;
                l2=l2.next;
            }
            ListNode newList = new ListNode(sum%10);
            newList.next=addHelper(l1,l2,sum/10);
            return newList;
        }
    }
    
    0 赞同 0 条回复
  • 晓宇 普通 2024年11月22日 下午9:23
    class soluntion{
    public:
        LinkList *add(LinkList *l1, LinkList *l2){
            LinkList *rl1 = reverse(l1);
            LinkList *rl2 = reversse(l2);
            LinkList ans, *p;  // 虚拟头节点 ans, 用于输出
            ans.next = p;
            int carry = 0;
            
            while(rl1 || rl2){
                carry = 0
                // 位数不等部分的处理
                if(rl1 && !rl2){
                   p->next = getNewNode(rl1->val);
                   p=p->next; 
                   rl1 = rl1->next;            
                }else if(!rl1 & rl2){
                   p->next = getNewNode(rl2->val); 
                   p=p->next;    
                   rl2 = rl2->next;                            
                }else{
                    // 相同位数部分的处理
                    p->next =  getNewNode((rl1->val + rl2->val) % 10) + carry;
                    p=p->next;
                    carry = (rl1->val + rl2->val + carry) / 10;
                    rl1 = rl1->next; 
                    rl2 = rl2->next; 
                }
            }
            // 如果存在尚未处理的进位
            if(carry == 1) p->next = getNewNode(carry);
            ans.next = ans.next->next; 
            return reverse(ans.next);
        } 
    
           LinkList *reverse(LinkList *head){
                if(!head || !(head->next))) return head;
                reverse(head->next);
                head->next->next = head;
                head->next = nullptr;                            
            }    
    
    }
    

    思路:先反转链表,再按位相加,这个过程中注意进位。最后再反转输出链表。
    时间复杂度:o(n) 空间复杂度 0(n)

    0 赞同 0 条回复
  • Jerry 普通 2024年11月22日 下午8:53
    class Solution {
    public:
        ListNode* reverseList(ListNode* head){
            if(!head || !head->next) return head;
            ListNode* newhead = reverseList(head->next);
            head->next->next = head;
            head->next = nullptr;
            return newhead;
        }
        ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
            ListNode* myhead = new ListNode(-1);
            ListNode* ptr = myhead;
            l1 = reverseList(l1);
            l2 = reverseList(l2);
            int flag = 0;
            while(l1 || l2){
                int n = 0;
                if(l1 && l2){
                   n = l1->val + l2->val + flag;
                }else if(l1){
                    n = l1->val + flag;
                }else if(l2){
                    n = l2->val + flag;
                }
    
                if(n >= 10){
                    flag = 1;
                    n = n - 10;
                }
                else{
                    flag = 0;
                }
                ptr->next = new ListNode(n);
                ptr = ptr->next;
                if(l1) l1 = l1->next;
                if(l2) l2 = l2->next;
            }
            if(flag){
                ptr->next = new ListNode(flag);
            }
            return reverseList(myhead->next);
    
        }
    };
    

    思路:反转两条链表,相加,同时记录进位
    时间o(n+m)
    空间o(1)

    0 赞同 0 条回复
  • WYX 普通 2024年11月22日 下午8:26

    思路: 首先 将两个链表逆转,然后依次同时遍历两个链表,并计算当前位结果。 需要设置carry表示当前位进位情况,用于后续操作。计算得到的结果通过头插法 构成 ans 结果列表。 需要关注最后一位计算完成后,是否需要进位,若需要进位,需额外添加一个Node。
    测试: 力扣 LCR 025. 两数相加 II LCR 025. 两数相加 II

    class Solution {
        public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            ListNode l1Reverse = reverse(l1);
            ListNode l2Reverse = reverse(l2);
    
            ListNode ans = new ListNode(-1, null);
            // 记录 进位 
            int carry = 0;
            while(l1Reverse != null && l2Reverse != null){
                int currentSum = l1Reverse.val + l2Reverse.val + carry;
                if(currentSum >= 10){
                    currentSum -= 10;
                    carry = 1;
                }else{
                    carry = 0;
                }
    
                ListNode currentNode = new ListNode(currentSum, null);
    
                // 将当前节点 插入 
                currentNode.next = ans.next;
                ans.next = currentNode;
    
                l1Reverse = l1Reverse.next;
                l2Reverse = l2Reverse.next;
    
            }
    
            while(l1Reverse != null){
                int currentSum = l1Reverse.val + carry;
                if(currentSum >= 10){
                    currentSum -= 10;
                    carry = 1;
                }else{
                    carry = 0;
                }
    
                ListNode currentNode = new ListNode(currentSum, null);
    
                // 将当前节点 插入 
                currentNode.next = ans.next;
                ans.next = currentNode;
    
                l1Reverse = l1Reverse.next;
            }
    
            while(l2Reverse != null){
                int currentSum = l2Reverse.val + carry;
                if(currentSum >= 10){
                    currentSum -= 10;
                    carry = 1;
                }else{
                    carry = 0;
                }
    
                ListNode currentNode = new ListNode(currentSum, null);
    
                // 将当前节点 插入 
                currentNode.next = ans.next;
                ans.next = currentNode;
    
                l2Reverse = l2Reverse.next;
            }
    
            if(carry == 1){
                // 存在进位 
                ListNode currentNode = new ListNode(1, null);
    
                // 将当前节点 插入 
                currentNode.next = ans.next;
                ans.next = currentNode;
            }
    
            return ans.next;
        }
    
        public ListNode reverse(ListNode node){
            ListNode ans = new ListNode(-1, null);
    
            while(node != null){
                ListNode current = node.next;
    
                node.next = ans.next;
                ans.next = node;
    
                node = current;
            }
    
            return ans.next;
        }
    }
    
    0 赞同 0 条回复
  • 迢迢星野 普通 2024年11月22日 下午7:49
    class Solution {
        public ListNode addTwoNumbers(ListNode head1, ListNode head2) {
            // 方式一:链表 -> 数字,求和,和 -> 链表 
            // 方式二:两个数字相加是从低位开始相加,反转两个链表,逐个相加,创建新链表,再反转新链表即可。
    
            // 1. 反转两个链表
            ListNode h1 = reverse(head1);
            ListNode h2 = reverse(head2);
    
            // 2. 创建虚拟头节点,用于构建新链表
            ListNode dummy = new ListNode(-1);
            ListNode cur = dummy;
            // 两个节点之和的进位
            int t = 0; 
    
            // 3. 构建新链表
            while (h1 != null || h2 != null || t != 0) {
                if (h1 != null) {
                    t += h1.val;
                    h1 = h1.next;
                }
                if (h2 != null) {
                    t += h2.val;
                    h2 = h2.next;
                }
                // 创建新链表的新节点
                cur.next = new ListNode(t % 10);
                t /= 10;
                cur = cur.next;
            }
    
            // 4. 反转新链表并返回
            ListNode newHead = reverse(dummy.next);
            return newHead;
        }
    
        private ListNode reverse(ListNode node) {
            ListNode pre = null, cur = node, tmp = null;
            while (cur != null) {
                tmp = cur.next;
                cur.next = pre;
                pre = cur;
                cur = tmp;
            }
            return pre;
        }
    }
    

    思路:链表的节点是从高位到低位存储的,而两个数的加法则是从低位到高位进行运算的,因此需要先将两个链表反转;再对反转后的链表节点一一求和,并组成新链表;将构建的新链表再次反转,确保链表的顺序就是所求的解。
    时间复杂度:O(n + m),最大的时间复杂度则是在反转了两个链表。
    空间复杂度:O(max(m, n)),两个链表求和后的链表的长度是两个链表的最大值(最多还要加 1)。

    0 赞同 0 条回复

# 回答此问题

后才能回答