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

本问题对应课程链接:剑指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 个回答

  • mpweixin用户 普通 2024年5月14日 上午11:54

    打卡成功

    0 赞同 0 条回复
  • Prime 普通 2023年9月6日 上午10:49

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

    # 反转单链表
    def reverseList(head):
        pre = None
        cur = head
        while cur:
            nxt = cur.next
            cur.next = pre
            pre = cur
            cur = nxt
        return pre
    
    # 链表相加
    def addTwoNumbers(l1, l2):
        # 先反转
        l1 = reverseList(l1)
        l2 = reverseList(l2)
    
        p1 = l1
        p2 = l2
    
        # 相加
        dummy = cur = ListNode(0)
        carry = 0
        while p1 or p2:
            x = p1.val if p1 else 0
            y = p2.val if p2 else 0
            sum = x + y + carry
            cur.next = ListNode(sum % 10)
            cur = cur.next
            carry = sum // 10
            if p1: p1 = p1.next
            if p2: p2 = p2.next
    
        # 反转结果链表 
        dummy.next = reverseList(dummy.next)
        return dummy.next
    
    
    0 赞同 0 条回复
  • 黎明之前 普通 2023年8月28日 上午7:46

    //两数相加 先将数据链表反转再进行计算 两个链表中的对应位置中存在值则相加 得出的值得10位加1 得个位为当前值 在每次计算后计算下一位
    public ListNode reverseList(LIstNode node)
    {
    ListNode pre=NULL;
    ListNode q= NULL;
    while(node!= NULL)
    {
    q= node.next;
    node.next = pre;
    pre= node;
    node = q;
    }
    public ListNode addTwoNumbers(LIstNode l1,ListNode l2)
    {
    ListNode listnode = new ListNode(0);
    ListNode p = listnode;
    int sum=0;
    while(l1!= NULL||l2!= NULL||sum0)
    {
    if(l1 != NULL)
    {
    sum += l1->val;
    l1= l1->val;
    }
    if(l2!=NULL)
    {
    sum +=l2->val;
    l2= l2->next;
    }
    p->next = new ListNode(sum%10);
    sum =sum/10;
    p= p->next;
    }
    return ListNode->next;
    }
    }

    0 赞同 0 条回复
  • 谁仁 普通 2023年8月24日 下午3:07

    struct node *addTwoNumber(struct node * lane1,struct node * lane2)
    {
    struct node * dummy = (struct node *)malloc(sizeof(struct node));//创建dummy节点,最终结果的头节点
    struct node * curr = dummy;
    int carry = 0 ;
    while(lane1 != NULL || lane2 != NULL)//遍历l1 l2,直到为空
    {
    int sum = carry;
    if(lane1 != NULL)
    {
    sum += lane1->val;
    lane1=lane1->next;
    }
    if(lane2 != NULL)
    {
    sum += lane2->val;
    lane2=lane2->next;
    }
    curr->next = (struct node *)malloc(sizeof(struct node *));
    curr = curr->next;//节点往下走,相加
    curr->val = sum%10;//判断进位
    carry = sum/10;
    }
    if(carry > 0)
    {
    curr->next = (struct node *)malloc(sizeof(struct node *));
    curr = curr->next;
    curr->val = carry;//如果遍历完,仍存在进位,则需要进行进位的值
    }
    curr->next = NULL;
    struct node * due = dummy->next;
    free(dummy);
    return due;
    }//时间复杂度为O(n),空间复杂度为O(1)

    0 赞同 0 条回复
  • 小火 普通 2023年8月22日 下午10:23

    leetcode445:先反转链表,再相加,再反转链表
    时间复杂度:o(n)
    空间复杂度:o(n)

    /**
     * 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 {
    
    private:
        ListNode* reverse2(ListNode* pre, ListNode* cur) {
            if(cur == nullptr) return pre;
            ListNode* res = cur->next;
            cur->next = pre;
            return reverse2(cur, res);
        }
        ListNode* reverse(ListNode* L) {
            return reverse2(nullptr, L);
        }
    
    public:
        ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
            l1 = reverse(l1);
            l2 = reverse(l2);
    
            ListNode* cur = new ListNode();
            ListNode* dummy = cur;
            int carry = 0, sum = 0;
    
            while(l1!=nullptr || l2!=nullptr) {
                int num1 = (l1!=nullptr)? l1->val:0;
                int num2 = (l2!=nullptr)? l2->val:0;
                sum = num1 + num2 + carry;
                cur->next = new ListNode(sum%10);
                carry = sum/10;
                cur = cur->next;
                if(l1!=nullptr) l1 = l1->next;
                if(l2!=nullptr) l2 = l2->next;
    
            }
            if(carry>0) cur->next = new ListNode(carry);
            return reverse(dummy->next);
    
        }
    };
    
    0 赞同 0 条回复
  • 漂洋过海去见你 永久会员 2023年8月21日 下午10:51

    #python题解:
    #特殊场景:9->9 + 1->1->9
    class Solution(object):
    def addTwoNumbers(self, l1, l2):
    “””
    :type l1: ListNode
    :type l2: ListNode
    :rtype: ListNode
    “””
    head = ListNode(0)
    cur = head
    remaining = 0
    while l1 or l2:
    if l1 None:
    cur.next = l2
    #此处是为了将剩下的l2.val + 进位 + 0,使得加的l1不空,得到的remaining用作下一个节点的val和进位
    l1 = ListNode(0)
    if l2
    None:
    cur.next = l1
    l2 = ListNode(0)

            remaining += l1.val + l2.val
            cur.next = ListNode(remaining % 10)
            remaining = remaining // 10
            cur = cur.next
            l1 = l1.next
            l2 = l2.next
        if remaining:
            cur.next = ListNode(remaining)
        return head.next
    
    0 赞同 0 条回复
  • mpweixin用户 普通 2023年8月21日 下午7:39

    参考的力扣445. 两数相加 II

    /**
     * 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) {
            stack<int>s1;
            stack<int>s2;
            while(l1 != nullptr|| l2 != nullptr){//把数据分别放入栈1 2
                if(l1 != nullptr){
                    s1.push(l1->val);
                    l1 = l1->next;
                }
    
                if(l2 != nullptr){
                    s2.push(l2->val);
                    l2 = l2->next;
                }
            }
    
            //开始取值相加
            ListNode *dummy = new ListNode(0);
            ListNode *cur = dummy;
            int val1, val2,carry=0,sum=0;
            while(!s1.empty() || !s2.empty() || carry != 0){
                if(!s1.empty()){
                    val1 = s1.top();
                    s1.pop();
                }else val1 = 0;
    
                if(!s2.empty()){
                    val2 = s2.top();
                    s2.pop();
                }else val2 = 0;
    
                sum = val1 + val2 + carry;
                carry = sum / 10;
                ListNode *newNode = new ListNode(sum%10);
                //头插法
                newNode->next = dummy->next;
                dummy->next = newNode;
            }
            return dummy->next;
    
    
        }
    };
    
    0 赞同 0 条回复
  • sincere 普通 2023年8月21日 下午6:10
    • 思路:参考 leetcode 445. 两数相加 II 先翻转链表,逐个求和后得到新链表,再翻转回去
    • 复杂度:时间复杂度O(n),空间复杂度O(n)
    class Solution {
        public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            ListNode p1 = reverseList(l1);
            ListNode p2 = reverseList(l2);
            ListNode l3 = addTwo(p1, p2, 0);
            return reverseList(l3);
        }
    
        public ListNode reverseList(ListNode head) {
            if (head == null || head.next == null) {
                return head;
            }
            ListNode newHead = reverseList(head.next);
            head.next.next = head;
            head.next = null;
            return newHead;
        }
    
        public ListNode addTwo(ListNode l1, ListNode l2, int carry) {
            if (l1 == null && l2 == null) {
                return carry != 0 ? new ListNode(carry) : null;
            }
            if (l1 == null) {
                l1 = l2;
                l2 = null;
            }
            carry += l1.val + (l2 != null ? l2.val : 0);
            l1.val = carry % 10;
            l1.next = addTwo(l1.next, (l2 != null ? l2.next : null), carry / 10);
            return l1;
        }
    
    }
    
    0 赞同 0 条回复
  • sc_Yang 普通 2023年8月20日 下午5:59
    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* reverseList(ListNode* head) {
            // ListNode tmpNode(-1);
            if(!head){
                return NULL;
            }
            ListNode* cur = head->next;
            ListNode* pre = head;
            while(cur){
                ListNode* tmpNode = cur->next;
                if(pre==head){
                    pre->next = NULL;
                }
                cur->next = pre;
                pre = cur;
                cur = tmpNode;
            }
            // 跳出时cur为NULL故返回时使用pre,跳出前已将最后一个值赋给pre
            return pre;
        }
        public ListNode* add2Numbers(ListNode* head1, ListNode* head2){
            head1 = reverseList(head1);
            head2 = reverseList(head2);
            ListNode* listNode = new ListNode(0);
            ListNode* p = listNode;
            int sum = 0; // sum用来存放进位
            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;
                }
                // 存储当前计算值,mod10
                p->next = new listNode(sum%10);
                // 存储当前计算的进位
                sum = sum/10;
                // 更新当前p节点的指针
                p = p->next;
            }
            return reverseList(listNode->next);
        }
    };
    
    0 赞同 0 条回复
  • QQiing 普通 2023年8月19日 下午4:37

    先将两个链表反转,然后进行列表相加,最后再反转一下。

    
    class SolutionAdd {
        ListNode* reverseList(ListNode* head)
        {
            ListNode* cur;
            ListNode* pre;
            ListNode* tmp;
            cur = head;
            pre = NULL;
            while(cur){
                tmp = cur->next;
                cur->next = pre;
                pre = cur;
                cur = tmp;
            }
            return pre;
        }
    
        ListNode* addList(ListNode* l1, ListNode* l2)
        {
            l1 = reverseList(l1);
            l2 = reverseList(l2);
            ListNode* listNode = new ListNode(0);
            ListNode* temp = listNode;
            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;
            }
            ListNode* result =reverseList(listNode.next) 
            return result;
        }
    }
    

    时间复杂度为O(n),空间复杂度为O(1)

    0 赞同 0 条回复
  • 天亮说晚安 普通 2023年8月19日 下午2:39

    思路:先将列表反转,相加后再次反转

    0 赞同 0 条回复
  • mpweixin用户 普通 2023年8月18日 下午11:45

    //首先将俩链表进行反转;
    //其次将反转链表的每个值相加,Count做为进位值。
    //时间复杂度为o(n)
    //空间复杂度为o(1)
    class Solution {
    public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {

        //这一步可以合并成一个函数。
        ListNode *ha=l1;
        ListNode *hb=l2;
        ListNode *prea=NULL;
        ListNode *preb=NULL;
        while (ha){
            ListNode *tmp=ha->next;
            ha->next=prea;
            prea=ha;
            ha=tmp;
        }
        while (hb){
            ListNode *tmp=hb->next;
            hb->next=preb;
            preb=hb;
            hb=tmp;
        }
    
        ListNode *res=new ListNode(0);
        ListNode *p=res;
        int Count =0;
    
        while(prea&&preb){
            int Sum =0;
            Sum = prea->val+preb->val;
            if(Sum>9){
                p->next = new ListNode(Sum%10);
                Count =Sum/10;
                p=p->next;
            }else if(Sum<10){
                p->next=new ListNode(Sum);
                if(Count>0){
                    p->next->val+=Count;
                }
                p=p->next;
            }
    
            prea=prea->next;
            preb=preb->next;
        }
        return res->next;
    }
    

    };

    0 赞同 0 条回复
  • Delete隐身 普通 2023年8月18日 下午11:00

    思路:先反转两个链表,然后遍历两个链表,每次得到进位和一个当前位的值,使用当前位的值构造一个新节点并插入到插入到链表的头节点处,直到两个链表都遍历完并且进位为0
    时间复杂度:O(N),空间复杂度:O(N)
    class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    l1 = reverse(l1);
    l2 = reverse(l2);
    int sum = 0;
    int flag = 0;
    ListNode cur = null;
    while(l1 != null || l2 != null || flag != 0) {
    sum = sum + (l1 != null ? l1.val : 0);
    sum = sum + (l2 != null ? l2.val : 0);
    sum += flag;
    flag = sum / 10;
    sum %= 10;
    ListNode temp = new ListNode(sum);
    temp.next = cur;
    cur = temp;
    }
    return cur;

    }
    
    // 反转链表:原地反转单链表
    public ListNode reverse(ListNode head) {
        if(head == null) {
            return head;
        }
        ListNode cur = head;
        ListNode pre = null;
        while(cur != null) {
            ListNode next = cur.next;
            cur.next = pre;
            pre = next;
            cur = cur.next;
            pre = pre.next;
        }
        return pre;
    }
    

    }

    0 赞同 0 条回复
  • Marc 普通 2023年8月17日 下午11:46
    之前的反转链表 + 链表相加 + 反转链表
    Class Solution:
        def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
            sum = 0
            dump = ListNode(-1)
            cur = dump
            while l1 and l2:
                cur.next = ListNode((l1.val + l2.val + sum) % 10)
                sum = (l1.val + l2.val + sum) // 10 
                l1, l2, cur = l1.next, l2.next, cur.next 
            if l2:
                l1 = l2 
            while l1:
                cur.next = ListNode((l1.val + sum) % 10)
                sum = (l1.val + sum) // 10 
                l1, cur = l1.next, cur.next             
    
            if sum > 0:
                cur.next = ListNode(sum) 
    
            return dump.next
    
    0 赞同 0 条回复
  • 一个人的风海吹了两遍 普通 2023年8月17日 下午2:38

    //头插法反转链表
    public ListNode reverseList(ListNode head) {
    if(headnull)
    return null;
    ListNode temp = new ListNode(0);
    ListNode pre = head;

        while(pre!=null){
            head= head.next;
            pre.next = temp.next;
            temp.next=pre;
            pre=head;
        }
        return temp.next;
    }
    //两条单链表做加法
    public ListNode ListAdd(ListNode head1, ListNode head2){
        head1 = reverseList(head1);
        head2 = reverseList(head2);
        ListNode cur1 = head1, cur2 = head2;
        //temp是进位,逐个相加相加得到的个位两个链的节点都赋值
        int temp=0;
        while (cur1!=null && cur2!=null){
            int sum = cur1.val + cur2.val + temp;
            cur1.val=sum%10;
            cur2.val=sum%10;
            temp = sum>=10 ? 1 : 0;
            cur1 = cur1.next;
            cur2 = cur2.next;
        }
        if(cur1==null && cur2==null && temp==1){  //两个链长度一样且最后相加有进位,加到一链后
            ListNode add = new ListNode(1);
            cur1.next=add;
        }else if (cur1 == null) { //一链短二链长
            cur2.val+=temp;
        }else if (cur2 == null) { //二链短一链长
            cur1.val+=temp;
        }
    
        head1 = reverseList(head1);  //反转一链,返回一链
        return head1;
    }
    
    0 赞同 0 条回复
  • Miracle· 普通 2023年8月17日 下午2:14

    时间复杂度
    /**
    * struct ListNode {
    * int val;
    * struct ListNode next;
    * ListNode(int x) : val(x), next(nullptr) {}
    * };
    */
    class Solution {
    public:
    /**
    * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
    *
    *
    * @param head1 ListNode类
    * @param head2 ListNode类
    * @return ListNode类
    */
    ListNode
    ReverseList(ListNode *head) {
    if (head nullptr) return nullptr;
    ListNode *cur = head;
    ListNode *pre = nullptr;
    while (cur) {
    // 断开链表,需要记录后续第一个节点位置
    ListNode *next = cur->next;
    // 将当前节点的next指向先前节点
    cur->next = pre;
    // 将先前节点更新为当前节点
    pre = cur;
    // 将当前节点更新为原链表中的下一个节点
    cur = next;
    }
    return pre;
    }

    ListNode* addInList(ListNode* head1, ListNode* head2) {
        // write code here
        if (head1 == nullptr) {
            return head2;
        }
        if (head2 == nullptr)
        {
            return head1;
        }
        // 反转两个链表
        head1 = ReverseList(head1);
        head2 = ReverseList(head2);
        // 添加表头
        ListNode *res = new ListNode(-1);
        ListNode *head = res;
        // 进位符号
        int carry = 0;
        // 当链表哦存在或者进位存在
        while (head1 || head2 || carry) {
            // 链表值不为空取值,否则设置为0
            int val1 = head1 != nullptr ? head1->val : 0;
            int val2 = head2 != nullptr ? head2->val : 0;
            int temp = val1 + val2 + carry;
            carry = temp / 10;
            temp %= 10;
            // 添加元素
            head->next = new ListNode(temp);
            head = head->next;
            // 移动到链表下一个元素
            if (head1) head1 = head1->next;
            if (head2) head2 = head2->next;
        }
        // 因为此时的结果依然是反的,需要将结果反转
        return ReverseList(res->next);
    }
    

    };

    0 赞同 0 条回复
  • 💮黧大王.exe 普通 2023年8月17日 上午9:49

    /**
    * Definition for singly-linked list.
    * struct ListNode {
    * int val;
    * ListNode next;
    * ListNode(int x) : val(x), next(NULL) {}
    * };
    */
    class Solution {
    public:
    ListNode
    reverseList(ListNode* head) {
    if(headNULL||head->nextNULL){
    return head;
    }
    ListNode pre=NULL,cur=head;
    while(cur!=NULL){
    ListNode t=cur->next;
    cur->next=pre;
    pre=cur;
    cur=t;
    }
    return pre;
    }
    ListNode
    addList(ListNode* l1, ListNode* l2) {
    nt jinwei=0;
    ListNode* result=new ListNode(0);
    ListNode* t=result;
    while(l1!=NULL||l2!=NULL){
    int n1 = l1 ? l1->val: 0;
    int n2 = l2 ? l2->val: 0;
    int sum=n1+n2+jinwei;
    jinwei=sum/10;
    if(l1!=NULL)
    l1=l1->next;
    if(l2!=NULL)
    l2=l2->next;
    t->next=new ListNode(sum%10);
    t=t->next;
    }
    if (jinwei > 0) {
    t->next = new ListNode(jinwei);
    }
    return result->next;
    }
    };
    时间复杂度:O(n+m)
    空间复杂度:O(1)

    0 赞同 0 条回复
  • Sheng 永久会员 2023年8月16日 下午3:04

    时间复杂度O(n)空间复杂度O(n)
    反转链表的函数是用的前一天的代码
    ”’java
    public ListNode addListNode(ListNode headA, ListNode headB)
    {
    if(headA null) return headB;
    if(headB
    null) return headA;

        ListNode revA = reverseList(headA);
        ListNode revB = reverseList(headB);
    
        ListNode sum;
        ListNode tail = sum;
        int remainder = 0;
        while(revA != null && revB != null) {
            tail = new ListNode((revA.val+revB.val)%10 + remainder);
            remainder = (revA.val+revB.val)/10;
            tail = tail.next;
            revA = revA.next;
            revB = revB.next;
        }
        if(revA == null && revB != null) {
            revB.val = revB.val + remainder;
            tail = revB;
            }
        if(revB == null && revA != null) {
            revA.val = revA.val + remainder;
            tail = revA;
        }
        return reverseList(sum);
    }
    
    0 赞同 0 条回复
  • mpweixin用户 永久会员 2023年8月16日 下午12:03

    ListNode* addList(ListNode* headA, ListNode* headB) {
    if (!headA) return headB;
    if (!headB) return headA;

    // 得到反转链表
    ListNode* reHeadA = reverseList(headA);
    ListNode* reHeadB = reverseList(headB);
    
    // 建立一个哑节点,用尾插法
    ListNode* dummy = new ListNode(0);
    ListNode* tail = dummy;
    int carry = 0;
    
    while (reHeadA || reHeadB || carry) {
        int sum = (reHeadA ? reHeadA->val : 0) + (reHeadB ? reHeadB->val : 0) + carry;
        carry = sum / 10;
    
        ListNode* newNode = new ListNode(sum % 10);
        tail->next = newNode;
        tail = tail->next;
    
        if (reHeadA) reHeadA = reHeadA->next;
        if (reHeadB) reHeadB = reHeadB->next;
    }
    
    return reverseList(dummy->next);
    

    }

    0 赞同 0 条回复
  • 小肸 永久会员 2023年8月15日 下午10:06
    public ListNode addTwoList(ListNode head1, ListNode head2) {
        ListNode rOne = reverseList(head1);
        ListNode rTwo = reverseList(head2);
        ListNode dummyHead = new ListNode(-1);
        ListNode cur = dummyHead;
        int carry = 0;
        while (rOne != null && rTwo != null) {
            int val = rOne.val + rTwo.val + carry;
            ListNode tmp = new ListNode(val % 10);
            cur.next = tmp;
            cur = cur.next;
            carry = (val >= 10 ? 1 : 0);
            //两个链表都向前移动一步
            rOne = rOne.next;
            rTwo = rTwo.next;
        }
        rOne = (rOne == null ? rTwo : rOne);
        while (rOne != null) {
            int val = rOne.val + carry;
            ListNode tmp = new ListNode(val % 10);
            cur.next = tmp;
            cur = cur.next;
            carry = (val >= 10 ? 1 : 0);
            rOne = rOne.next;
        }
        //特性情况,考虑9和1之类的
        if (carry == 1) {
            cur.next = new ListNode(1);
            cur = cur.next;
        }
        return reverseList(dummyHead);
    }
    ListNode reverseList(ListNode head) {
        ListNode pre = null;
        while (head != null) {
            ListNode tmp = head.next;
            head.next = pre;
            pre = head;
            head = tmp;
        }
        return pre;
    }
    
    0 赞同 0 条回复
  • 木木 普通 2023年8月15日 下午3:20

    時間複雜度: O(M+N), O(1)
    核心: 維護一個sum 跟 carry 分別代表每次兩數相加的和跟要進位的數, 按照正常數學算法的邏輯去寫, 就挺容易, 最後答案要反轉才會是正確的

    
    #include < iostream >
    #include < vector >
    
    struct ListNode {
         int val;
         ListNode *next;
         ListNode(int x) : val(x), next(NULL) {}
     };
    
    ListNode * reverse(ListNode* head) {
        ListNode* prev = NULL;
        ListNode* curr = head;
        while (curr != NULL) {
            ListNode* next = curr->next;
            curr->next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }
    
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* head = NULL;
        ListNode* tail = NULL;
        int carry = 0;
        while (l1 != NULL || l2 != NULL) {
            int sum = carry; // this store the carry from the previous iteration
            if (l1 != NULL) {
                sum += l1->val;
                l1 = l1->next;
            }
            if (l2 != NULL) {
                sum += l2->val;
                l2 = l2->next;
            }
            carry = sum / 10;
            ListNode* node = new ListNode(sum % 10);
            if (head == NULL) {
                head = node;
                tail = node;
            } else {
                tail->next = node;
                tail = node;
            }
        }
        if (carry > 0) {
            ListNode* node = new ListNode(carry);
            tail->next = node;
        }
        head = reverse(head);
        return head;
    
    }
    
    int main () {
        ListNode* l1 = new ListNode(7);
        ListNode* l2 = new ListNode(8);
        ListNode* l3 = new ListNode(9);
        l1->next = l2;
        l2->next = l3;
    
        ListNode* l4 = new ListNode(3);
        ListNode* l5 = new ListNode(2);
        ListNode* l6 = new ListNode(1);
        l4->next = l5;
        l5->next = l6;
    
        ListNode* result = addTwoNumbers(l1, l4);
        while (result != NULL) {
            std::cout << result->val << std::endl;
            result = result->next;
        }
        return 0;
    }
    
    
    0 赞同 0 条回复
  • 行动派小彩笔 普通 2023年8月15日 下午1:56
    //时间复杂度O(n+m),空间复杂度O(1)
    /**
     * struct ListNode {
     *  int val;
     *  struct ListNode *next;
     *  ListNode(int x) : val(x), next(nullptr) {}
     * };
     */
    #include <bits/types/struct_tm.h>
    #include <list>
    class Solution {
    public:
        /**
         * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
         * 
         * 
         * @param head1 ListNode类 
         * @param head2 ListNode类 
         * @return ListNode类
         */
        ListNode* reverseList(ListNode* head)
        {
            if(!head) return head;
            ListNode *pre =nullptr;
            ListNode *cur = head;
            while (cur) {
                ListNode *tmp = cur->next;
                cur->next = pre;
                pre = cur;
                cur = tmp;
            }
            return pre;
        }
    
        ListNode* addInList(ListNode* head1, ListNode* head2) {
            // write code here
            ListNode* newHead1 = reverseList(head1);
            ListNode* newHead2 = reverseList(head2);
    
            ListNode* cur1 = newHead1,*cur2 = newHead2;
    
            ListNode* ansHead = new ListNode(-1);
            ListNode* ans = ansHead;
            int flag = 0;
            while(cur1 || cur2)
            {   
                int val1 = cur1?cur1->val:0;
                int val2 = cur2?cur2->val:0;
                int sum = val1 + val2 + flag;
                if(sum>=10)
                {
                    flag = 1;
                    sum = sum%10;
                }
                else flag = 0;
                ans->next = new ListNode(sum);
                ans = ans->next;
                if(cur1)cur1= cur1->next;
                if(cur2)cur2= cur2->next;
            }
            if(flag) ans->next = new ListNode(1);
            ans = reverseList(ansHead->next);
            return ans;
        }
    };
    
    0 赞同 0 条回复
  • c 普通 2023年8月15日 下午12:33

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

    class ListNode {
        int val;
        ListNode next;
        ListNode(int x) { val = x; }
    }
    
    public class test {
        public ListNode reverse(ListNode head){
            if(head==null){
                return null;
            }
            ListNode node=head;
            ListNode next;
            head=head.next;
            node.next=null;
            while(head!=null){
                next=head.next;
                head.next=node;
                node=head;
                head=next;
            }
            return node;
        }
    
        public ListNode add(ListNode head1,ListNode head2){
            ListNode head = new ListNode(0);
            ListNode node = head;
            head1=reverse(head1);
            head2=reverse(head2);
            int c=0;
            while (head1!=null && head2!=null){
                c=head1.val+head2.val+c;
                node.next=new ListNode(c%10);
                node=node.next;
                c=c/10;
                head1=head1.next;
                head2=head2.next;
            }
            while (head1!=null){
                c=head1.val+c;
                node.next=new ListNode(c%10);
                node=node.next;
                c=c/10;
                head1=head1.next;
            }
            while (head2!=null){
                c=head2.val+c;
                node.next=new ListNode(c%10);
                node=node.next;
                c=c/10;
                head2=head2.next;
            }
            if (c!=0){
                node.next=new ListNode(c%10);
                node=node.next;
            }
            return reverse(head.next);
        }
        public static void main(String[] args) {
            test solution = new test();
            ListNode a1 = new ListNode(1);
            ListNode a2 = new ListNode(2);
            ListNode a3 = new ListNode(3);
            ListNode a4 = new ListNode(4);
            ListNode b1 = new ListNode(3);
            ListNode b2 = new ListNode(4);
            a1.next = a2;
            a2.next = a3;
            a3.next = a4;
            b1.next = b2;
            ListNode listNode = solution.add(a1, b1);
            while (listNode != null) {
                System.out.print(listNode.val);
                listNode = listNode.next;
            }
        }
    }
    
    0 赞同 0 条回复
  • 逸兴遄飞 普通 2023年8月15日 上午10:18
    • 时间复杂度O(n);
    • 空间复杂度O(n)
      一开始想学之前的方法对t1和t2进行初始赋值,如:
    ListNode t1= new ListNode();
    

    但是这样赋值会导致t1原本就存在节点值为0,在后续相加时result会在开头多出值为0的结果,需要再去手动删去,不知道有没有更好的解决办法。

    class Solution {
        // 初始化result用于存储结果,t1和t2用于传递加数
        ListNode result;
        ListNode t1, t2;
        public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            // 分别向t中存入相加值
            while(l1 != null){
                t1 = push(l1.val, t1);
                l1 = l1.next;
            }
            while(l2 != null){
                t2 = push(l2.val, t2);
                l2 = l2.next;
            }
            // 对每对数据进行加法操作
            add(t1, t2, 0);
            return result;
        }
    
        // 定义加法操作
        public void add(ListNode l1, ListNode l2, int sum){
            if(l1 == null && l2 == null && sum == 0){
                return;
            }
            if(l1 != null){
                sum += l1.val;
                l1 = l1.next;
            }
            if(l2 != null){
                sum += l2.val;
                l2 = l2.next;
            }
            push(sum % 10);
            sum /= 10;
            // 在此进行递归
            add(l1, l2, sum);
        }
    
        // 定义传值操作
        public void push(int x){
            ListNode p = new ListNode(x);
            p.next = result;
            result = p;
        }
    
        // 定义链表next传值函数
        public ListNode push(int x, ListNode t){
            ListNode p = new ListNode(x);
            p.next = t;
            return p;
        }
    }
    
    0 赞同 0 条回复
  • 晓宇 普通 2023年8月15日 上午8:20
    class Solution(object):
        def addTwoNumbers(self, l1, l2):
            """
            :type l1: ListNode
            :type l2: ListNode
            :rtype: ListNode
            """
            head1 = l1
            head2 = l2
            if not head1:
                return head2
            if not head2:
                return head1
            head3 = ListNode(0)
            root = head3
            capital = 0
    
    <pre><code>    while(head1 and head2):
            sum_all = head1.val + head2.val + capital
            capital = sum_all // 10
            sum_num = sum_all % 10
            head3.next = ListNode(sum_num,None)
            head3 = head3.next
            head1 = head1.next
            head2 = head2.next
    
        while(head1):
            sum_all = head1.val + capital
            capital = sum_all // 10
            sum_num = sum_all % 10
            head3.next = ListNode(sum_num,None)
            head1 = head1.next
            head3 = head3.next
    
        while(head2):
            sum_all = head2.val + capital
            capital = sum_all // 10
            sum_num = sum_all % 10
            head3.next = ListNode(sum_num,None)
            head2 = head2.next
            head3 = head3.next
    
        if capital != 0:
            head3.next = ListNode(capital,None)
    
    
        return root.next
    
            def reserve_list(self,l1):
        # one point or None point doesn't need reserve
        if not l1 or not l1.next:
            return l1
        prev = None
        cur = l1
        while(cur):
            tmp = cur.next
            cur.next =prev
            prev = cur
            cur = tmp
        return prev
    </code></pre>
    
    

    1.For this question, becasue we need add from the last,and we don’t have two direction linked list,
    so we need parse this question in two problem (1)reserve linked list (2)add linked list
    (1)
    reserve need to consider prev and cur point
    (2)
    add need to consider capital and sum, how to handle Longer list and the last capital 差不多就是这样

    0 赞同 0 条回复
  • 别扒拉我 普通 2023年8月14日 下午11:12

    没想到。先反转链表,再逐个相加

    0 赞同 0 条回复
  • 木子有点甜🍒 普通 2023年8月14日 下午9:18

    “`python
    自己写是把求和和生成新节点联系在一起,对比参考代码之后发现我的做法很直白,对两个链表对应位置的节点相加,然后有进位就想对应的方法解决进位。参考代码的思想,主要需要解决的问题是动态的相加,相加的两个整数被存放在两个链表里,结果也要求被放在链表里,那么动态相加参照这样的结构:这是一个求和的过程,链表存储则按位相加,每一个位相加时,用一个sum变量存储位相加的值,值为sum%10(一个位只能存储<10的),然后生成新节点把结果存储下来。如果sum值大于等于10,则通过sum/10计算进位,进位是要与下一位计算相加的,所以下一位相加前用sum先把进位的1记录下来,然后循环前面操作。
    class SolutionAdd {
    // 反转链表
    public ListNode reverseList(ListNode node){
    pre = None
    tmp = None

    while tmp:
    tmp = node.next
    node.next = pre
    pre =node
    node = tmp
    }

    public ListNode addTwoNumbers(ListNode head1, ListNode head2) {
    if head1 None: return head2
    if head2
    None: return head1

    head1 = reverseList(head1)
    head2 = reverseList(head2)
    head = ListNode(-1)
    cur = ListNode(0)
    cur = head.next
    while head1 and head2:
    if head1.val+head2.val >=10:
    newnode = ListNode(1)
    cur.val = cur.val+head1.val+head2.val -10
    else:
    cur.val = head1.val + head2.val
    newnode = ListNode(0)
    }
    cur.next = newnode
    cur = cur.next
    head1 = head1.next
    head2 = head2.next

    if head1:cur.next = head2
    if head2:cur.next = head1
    }
    return reverseList(head.next)
    }

    0 赞同 0 条回复
  • mpweixin用户 永久会员 2023年8月14日 下午8:39

    先反转两个列表,然后逐个相加;
    时间复杂度O(n+m); 空间复杂度O(1)

    public class Solution {
        public ListNode addListNode(ListNode headA, ListNode headB) {
            if (headA == null) {
                return headB;
            }
            if(headB == null) {
                return headA;
            }
            ListNode reverseA = reverse(headA);
            ListNode reverseB = reverse(headB);
            ListNode dummyhead = new ListNode(-1);
            ListNode p = reverseA, q = reverseB;
            int sum = 0;
            while (p != null && q != null) {
                sum += p.val + q.val;
                ListNode current = new ListNode(sum % 10);
                current.next = dummyhead.next;
                dummyhead.next = current;
                sum /= 10;
                p = p.next;
                q = q.next;
            }
            while (p != null) {
                sum += p.val;
                ListNode current = new ListNode(sum % 10);
                current.next = dummyhead.next;
                dummyhead.next = current;
                sum /= 10;
                p = p.next;
    
            }
            while (q != null) {
                sum += q.val;
                ListNode current = new ListNode(sum % 10);
                current.next = dummyhead.next;
                dummyhead.next = current;
                sum /= 10;
                q = q.next;
            }
            return dummyhead.next;
        }
    
        public ListNode reverse(ListNode head) {
            ListNode dummyhead = new ListNode(-1);
            while(head != null) {
                ListNode temp = head.next;
                head.next = dummyhead.next;
                dummyhead.next = head;
                head = temp;
            }
            return dummyhead.next;
        }
    
        public static void main(String[] args) {
            Solution solution = new Solution();
            ListNode a1 = new ListNode(1);
            ListNode a2 = new ListNode(2);
            ListNode a3 = new ListNode(3);
            ListNode a4 = new ListNode(4);
            ListNode b1 = new ListNode(3);
            ListNode b2 = new ListNode(4);
            a1.next = a2;
            a2.next = a3;
            a3.next = a4;
            b1.next = b2;
            ListNode listNode = solution.addListNode(a1, b1);
            while (listNode != null) {
                System.out.print(listNode.val);
                listNode = listNode.next;
            }
        }
    }
    class ListNode {
        int val;
        ListNode next;
    
        public ListNode(int val) {
            this.val = val;
            this.next = null;
        }
    }
    
    0 赞同 0 条回复
  • Vince 普通 2023年8月14日 下午5:18

    class Solution(){
    先反转再相加
    main(){
    reverseList(l1);
    reverseList(l2);
    ListNode dummy = new ListNode();
    ListNode cur = dummy;
    boolean addOne = false;
    while(l1 != null && l2 != null){
    Node node = new ListNode();
    int sum = l1.val + l2.val;
    if(addOne) sum++;
    if(sum >= 10){
    node.val = sum – 10;
    addOne = true;
    }else{
    node.val = sum;
    addOne = false;
    }
    cur.next = node;
    cur = cur.next;
    l1 = l1.next;
    l2 = l2.next;
    }
    if(l1 != null){
    cur.next = l1;
    }else if(l2 != null){
    cur.next = l2;
    }
    if(cur.next){
    if(addOne){
    cur.next.val++;
    }
    }

        if(l1 == null && l2 == null && addOne){
            cur.next = new ListNode();
            cur.next.val = 1;
        }
    return dummy.next;
    
    
    }
    
    reverseList(ListNode node){
    
        ListNode cur = node;
        ListNode prev = null;
        while(cur.next != null){
            ListNode next = cur.next;
            cur.next = prev;
            cur = next;
            prev = cur;
        }
        cur.next = prev;
        return cur;
    

    }

    0 赞同 0 条回复
  • 辰北、 普通 2023年8月14日 下午5:10

    //fanzhuanhanshu1反转函数
    struct ListNode* reverseList(struct ListNode* head){
    struct ListNode *p1=head;
    struct ListNode *p2=NULL;
    while(p1){
    struct ListNode *pnext=p1->next;
    p1->next=p2;
    p2=p1;
    p1=pnext;
    //free(pnext);
    }
    return p2;

    }
    struct ListNode getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode *pA=headA;
    struct ListNode *pB=headB;
    struct ListNode *newA=NULL;
    struct ListNode *newB=NULL;
    struct ListNode *newSum=NULL;
    struct ListNode *Sum=NULL;
    int temp=0;
    /

    if(!pA){
    return pB;
    } else if(!pB){
    return pA;
    }
    else{//先反转;//pa= a b c d

        while(!pA){
            struct ListNode *pnext=pA->next;//pn=b
            pA->next=newA;//pa[1]=null;
            newA=pA;//newA[0] =a;
            pA=pnext;//b=pa[0];pA=pA->next   pA下移了一位;到b了;   
        }  
        while (!pB){
            struct ListNode *pnext=pB->next;
            pB->next=newB;//pa[1]=null;
            newB=pB;//newA[0] =a;
            pB=pnext;
        }
    }
    */
    if(!pA){
        return pB;  
    } else if(!pB){
        return pA;
    }
    else{//先反转;//pa= a b c d
        while(!pA){
            newA=reverseList(pA);       
        }  
        while (!pB){
            newB=reverseList(pB);
        }
    }
    //求和进位 
    while(!newA&&!newB){
        if(!newA||!newB){
        Sum->val=newA->val+newB->val;
            if(Sum->val>=10){
                Sum->val-10=Sum->next->val;
                Sum->val=0;
            }
            Sum=Sum->next;
            newA=newA->next;
            newB=newB-next; 
        }
        else if(!newA&&newB){
            Sum=newB;
        }
        else if(!newB&&newA){
            Sum=newA;
        }   
    }
    //反转sum;
    newSum=reverseList(sum);
    return newSum;                      
    

    }

    0 赞同 0 条回复
  • mpweixin用户 普通 2023年8月14日 下午4:20

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

    class Solution {
        public ListNode reverseList(ListNode head) {
            if(head == null || head.next == null){
                return head;
            }
            ListNode temp = null;
            temp = reverseList(head.next);
            head.next.next = head;
            head.next = null;
            return temp;
        }
        public ListNode addNumber(ListNode temp1,ListNode temp2) {
            int sum =0;
            ListNode head1 = new ListNode(0);
            ListNode head2 = head1;
            while(temp1 != null || temp2 != null || sum==1){
                if(temp1!=null){
                    sum += temp1.val;
                    temp1 = temp1.next;
                }
                if(temp2!=null){
                    sum += temp2.val;
                    temp2 = temp2.next;
                }
                head2.next =new ListNode(sum%10);
                sum = sum/10;
                head2 = head2.next;
            }
            return head1.next;
        }
    }
    
    0 赞同 0 条回复
  • Jou Siankwa 普通 2023年8月14日 下午2:59
    class ListNode {
        int val;
        ListNode next;
        ListNode(int x) { val = x; }
    }
    
    class Solution {
        // 反转链表
        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) {
            if(head1 == null){
                return head2;
            }else if(head2 == null){
                return head1;
            }
    
            ListNode listNode = new ListNode(0), p = listNode;
    
            ListNode node1 = reverseList(head1), node2 = reverseList(head2);
            // sum 用来存放进位
            int sum = 0;
            while (node1 != null || node2 != null || sum != 0) {
                if (node1 != null) {
                    sum += node1.val;
                    node1 = node1.next;
                }
    
                if (node2 != null) {
                    sum += node2.val;
                    node2 = node2.next;
                }
                p.next = new ListNode(sum % 10);
                sum = sum / 10;
                p = p.next;
            }
            p = listNode.next;
            listNode.next = null;
            return reverseList(p);
        }
    
        public static void main(String[] args) {
            Solution sol = new Solution();
            ListNode node1 = new ListNode(1);
            ListNode node2 = new ListNode(2);
            ListNode node3 = new ListNode(3);
            ListNode node4 = new ListNode(4);
            node1.next = node2;
            node2.next = node3;
            node3.next = node4;
    
            ListNode node5 = new ListNode(3);
            ListNode node6 = new ListNode(4);
            node5.next = node6;
            ListNode listNode = sol.addTwoNumbers(node1, node5);
            while(listNode != null){
                System.out.println(listNode.val);
                listNode = listNode.next;
            }
        }
    }
    

    时间复杂度O(n),空间复杂度O(n)

    0 赞同 0 条回复

# 回答此问题

后才能回答