[LeetCode] 445、两数相加 II

题目描述

给定两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。(如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转)

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

解题思路

本题有“后进先出”的特点,考虑用“栈”来解决,主要有两种思路:

  • 双栈解法(推荐,我的实现):遍历两个链表,将指向节点的指针存入两个栈中。从栈顶开始取节点的值求和。每求出一对节点的和,出栈节点。直到两栈都为空。
  • 递归解法(看看思路就好):先计算两个链表的长度,然后对短链表前面补0使两个链表长度相同,使用递归先计算最末尾节点,利用递归的回溯特性,不断更新carry进位与新的结果头节点。

参考代码

双栈法:

/**
 * 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) {
        vector<ListNode*> l1v, l2v;
        to_vector(l1, l1v);
        to_vector(l2, l2v);
        int i = l1v.size()-1, j = l2v.size()-1;
        int tempNum = 0;
        
        ListNode *dummyHead = new ListNode(-1);
        dummyHead->next = nullptr;
        while(i >= 0 || j >= 0){
            if(i >= 0) tempNum += l1v[i--]->val;
            if(j >= 0) tempNum += l2v[j--]->val;
            
            ListNode* tempNode = new ListNode(tempNum % 10);  // 头插法
            tempNode->next = dummyHead->next;
            dummyHead->next = tempNode;
            
            tempNum /= 10;
        }
        
        if(tempNum != 0) {  // 最后最高位是否有进位
            ListNode* tempNode = new ListNode(tempNum);
            tempNode->next = dummyHead->next;
            dummyHead->next = tempNode;
        }
        
        return dummyHead->next;
    }
    
    void to_vector(ListNode* head,vector<ListNode*>& v){
        while(head){
            v.push_back(head);
            head = head->next;
        }
    }

};

递归法:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    int length(ListNode *head) {
        if (head == nullptr) return 0;
        return 1 + length(head->next);
    }

    int addTwoNumbersHelper(ListNode *l1, ListNode *l2, ListNode *&res) {  // 必须用  *&
        if (l1 == nullptr || l2 == nullptr) return 0;
        int carry = addTwoNumbersHelper(l1->next, l2->next, res);
        int sum = l1->val + l2->val + carry;
        auto newHead = new ListNode(sum % 10);
        newHead->next = res;
        res = newHead;
        return sum / 10;
    }

    ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
        int m = length(l1), n = length(l2);
        ListNode *res = nullptr;

        // 让两个链表长度相同
        int carry = 0;
        if (m > n) {
            int k = m - n;
            ListNode *dummy = new ListNode(0);
            dummy->next = l2;
            while (k--) {
                ListNode *t = new ListNode(0);
                t->next = dummy->next;
                dummy->next = t;
            }
            carry = addTwoNumbersHelper(l1, dummy->next, res);

        } else if (m < n) {
            int k = n - m;
            ListNode *dummy = new ListNode(0);
            dummy->next = l1;
            while (k--) {
                ListNode *t = new ListNode(0);
                t->next = dummy->next;
                dummy->next = t;
            }
            carry = addTwoNumbersHelper(dummy->next, l2, res);
        } else {
            carry = addTwoNumbersHelper(l1, l2, res);
        }

        if (carry) {
            ListNode *newHead = new ListNode(1);
            newHead->next = res;
            res = newHead;
        }
        return res;
    }

};
发布了436 篇原创文章 · 获赞 626 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/ft_sunshine/article/details/104096282