【LeetCode-链表】两数相加 II

题目描述

给定两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例:

输入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出: 7 -> 8 -> 0 -> 7

题目链接:https://leetcode-cn.com/problems/add-two-numbers-ii/
做这题之前可以先做一下:两数相加题解

思路1

使用和两数相加基本一样,只多了链表反转的操作。代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        if(l1==nullptr && l2==nullptr){
            return nullptr;
        }

        l1 = reverseList(l1);
        l2 = reverseList(l2);
        int carry = 0;  // 当前进位
        ListNode* head = new ListNode(0);
        ListNode* curNode = head;
        while(l1!=nullptr || l2!=nullptr){
            int x = l1==nullptr? 0:l1->val;
            int y = l2==nullptr? 0:l2->val;
            int s = x+y+carry;
            ListNode* node = new ListNode(s%10);
            curNode->next = node;
            curNode = node;
            carry = s/10;
            if(l1!=nullptr) l1 = l1->next;
            if(l2!=nullptr) l2 = l2->next;
        }
        if(carry!=0){
            ListNode* node = new ListNode(carry);
            curNode->next = node;
        }
        head->next = reverseList(head->next);
        return head->next;
    }

    ListNode* reverseList(ListNode* head){  //反转链表
        ListNode* curNode = head;
        ListNode* preNode = nullptr;
        ListNode* nextNode = nullptr;
        while(curNode!=nullptr){
            nextNode = curNode->next;
            curNode->next = preNode;
            preNode = curNode;
            curNode = nextNode;
        }
        return preNode;
    }
};

别忘了最后的进位问题。

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

思路2

思路1需要对链表进行更改,也就是需要反转链表。如果不能反转链表,则可以借助栈来做。首先将两个链表中的数字分别压入两个栈中,然后弹出栈顶元素相加后,使用头插法插入到新链表中。代码如下

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        if(l1==nullptr && l2==nullptr){
            return nullptr;
        }

        stack<int> s1;
        stack<int> s2;
        while(l1!=nullptr){
            s1.push(l1->val);
            l1 = l1->next;
        }
        while(l2!=nullptr){
            s2.push(l2->val);
            l2 = l2->next;
        }
        
        int x, y, carry=0;
        ListNode* head = new ListNode(0);
        while(!s1.empty() || !s2.empty()){
            if(!s1.empty()){
                x = s1.top();
                s1.pop();
            }else{
                x = 0;
            }
            if(!s2.empty()){
                y = s2.top();
                s2.pop();
            }else{
                y = 0;
            }
            int s = x+y+carry;
            ListNode* node = new ListNode(s%10);
            node->next = head->next;    // 头插法
            head->next = node;
            carry = s/10;
        }
        if(carry!=0){
            ListNode* node = new ListNode(carry);
            node->next = head->next;
            head->next = node;
        }
        return head->next;
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
    需要借助栈,额外空间随着数据规模的增大线性增长。

相关题目

1、两数相加:https://leetcode-cn.com/problems/add-two-numbers/,题解
2、反转链表:https://leetcode-cn.com/problems/reverse-linked-list/,题解

posted @ 2020-04-10 20:28  Flix  阅读(172)  评论(0编辑  收藏  举报