zoukankan      html  css  js  c++  java
  • Leetcode 445. 两数相加 II

    1.题目描述

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

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

    进阶:

    如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。

    示例:

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

      

    2.解法一:反转链表

    2.1 思路

    (1)将两个链表反转,就变成了Leetcode上的第二道题目“2.两数相加”;

    (2)然后就是一样的思路:题中链表顺序正好是低位到高位,先低位相加,有进位保持,下一位计算加上进位,直到最高位相加,如果有进位,生成新的结点保存。

    2.2 代码

    class Solution {
    public:
         
         //反转链表
         ListNode* reverseList(ListNode* l3) {
            if (!l3) return NULL;
    
            ListNode* r = new ListNode(l3->val);
            ListNode* h = r;
            ListNode* cur = l3->next;
            while (cur) {
                ListNode* temp = new ListNode(cur->val);
                temp->next = h;
                h = temp;
                cur = cur->next;
            }
            return h;
        }
    
        ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
            
            //逆序
            l1 = Solution::reverseList(l1);
            l2 = Solution::reverseList(l2);
    
            unsigned int carry = 0; //进位
    
            ListNode* Hl3 = new ListNode(0);
            ListNode* l3 = Hl3;
    
            int a = 0;
            int b = 0;
            int temp = 0;
    
            while (l1 != NULL || l2 != NULL)
            {
                //判断a和b的取值
                if (l1 == NULL) a = 0;
                else a = l1->val;
                if (l2 == NULL) b = 0;
                else b = l2->val;
    
                temp = (a + b + carry) % 10;
    
                //有无进位
                if ((a + b + carry) / 10 != 0)
                    carry = 1;
                else
                    carry = 0;
    
                //创建新结点,保存temp
                l3->next = new ListNode(temp);
                l3 = l3->next;
    
                if (l1) l1 = l1->next;
                if (l2) l2 = l2->next;
            }
    
            //最后的进位
            if (carry == 1) {
                l3->next = new ListNode(1);
            }
            
            //还原链表
            Hl3->next = Solution::reverseList(Hl3->next);
            return Hl3->next;
        }
    };

    3.解法二:不允许反转(进阶)

    3.1 思路

    关键还是在于逆序结构适应于这种情况。不需要考虑空间复杂性的话,为了方便,使用三个栈

      • 前两个栈s1和s2逆序保存两个链表l1和l2的结点值;
      • 第三个栈s3来保存前两个栈相加的结果,还原链表顺序;

    3.2 代码

    #include <iostream>
    #include <stack>
    
    using namespace std;
    
    struct ListNode {
        int val;
        ListNode *next;
        ListNode(int x) : val(x), next(NULL) {}
    };
    
    class Solution {
    public:
        ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
            stack<int> s1;
            stack<int> s2;
            stack<int> s3;
    
            ListNode* Hl3 = new ListNode(0);
            ListNode* l3 = Hl3;
    
            //遍历两个链表入栈,进行逆序
            while (l1 != NULL) {
                s1.push(l1->val);
                l1 = l1->next;
            }
            while (l2 != NULL) {
                s2.push(l2->val);
                l2 = l2->next;
            }
    
            //用栈来相加
            int a = 0;
            int b = 0;
            int temp = 0;
            int carry = 0;
    
            while (!s1.empty() || !s2.empty()) {
                a = s1.size() == 0 ? 0 : s1.top();
                b = s2.size() == 0 ? 0 : s2.top();
                temp = a + b + carry;
    
                //有无进位
                carry = temp / 10 == 0 ? 0 : 1;
    
                s3.push(temp % 10);
                
                /*---常见错误总结---*/
                //不空,才能出栈
                if(!s1.empty()) s1.pop();
                if(!s2.empty()) s2.pop();
            }
            if (carry == 1)
                s3.push(1);
    
    
            //恢复顺序
            while (!s3.empty()) {
                l3->next = new ListNode(s3.top());
                l3 = l3->next;
                s3.pop();
            }
            return Hl3->next;
        }
    };
    
    int main()
    {
        ListNode* p1 = new ListNode(7);
        ListNode* p2 = new ListNode(2);
        ListNode* p3 = new ListNode(4);
        ListNode* p4 = new ListNode(3);
        p1->next = p2;
        p2->next = p3;
        p3->next = p4;
        p4->next = NULL;
    
        ListNode* q1 = new ListNode(5);
        ListNode* q2 = new ListNode(6);
        ListNode* q3 = new ListNode(4);
        q1->next = q2;
        q2->next = q3;
        q3->next = NULL;
    
        Solution test;
        ListNode* t1 = test.addTwoNumbers(p1, q1);
        while (t1) {
            cout << t1->val << endl;
            t1 = t1->next;
        }
        return 0;
    }
  • 相关阅读:
    LeetCode 189. Rotate Array
    LeetCode 965. Univalued Binary Tree
    LeetCode 111. Minimum Depth of Binary Tree
    LeetCode 104. Maximum Depth of Binary Tree
    Windows下MySQL的安装与配置
    LeetCode 58. Length of Last Word
    LeetCode 41. First Missing Positive
    LeetCode 283. Move Zeroes
    《蚂蚁金服11.11:支付宝和蚂蚁花呗的技术架构及实践》读后感
    删除docker下的镜像
  • 原文地址:https://www.cnblogs.com/paulprayer/p/10079731.html
Copyright © 2011-2022 走看看