• 【LeetCode-链表】两数相加


    题目描述

    给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
    如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
    您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
    示例:

    输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
    输出:7 -> 0 -> 8
    原因:342 + 465 = 807
    

    题目链接:https://leetcode-cn.com/problems/add-two-numbers/

    思路

    用链表来模拟人做加法,注意每一位的进位,以及最后是否有进位。最后如果有进位的话,则需要多加一个节点。代码如下:

    /**
     * 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;
            }
    
            int carry = 0;  // 当前的进位
            ListNode* head = new ListNode(0);   // 新链表的链表头
            ListNode* curNode = head;
            while(l1!=nullptr && l2!=nullptr){
                int s = l1->val+l2->val+carry;
                ListNode* node = new ListNode(s%10);
                carry = s/10;
                curNode->next = node;
                curNode = node;
                l1 = l1->next;
                l2 = l2->next;
            }
            if(l1==nullptr && l2!=nullptr){ //说明l1比较短,将l2剩余的部分加入到新链表当中
                while(l2!=nullptr){
                    int s = l2->val+carry;
                    ListNode* node = new ListNode(s%10);
                    carry = s/10;
                    curNode->next = node;
                    curNode = node;
                    l2 = l2->next;
                }
            }
            if(l1!=nullptr && l2==nullptr){ //说明l2比较短,将l1剩余的部分加入到新链表当中
                while(l1!=nullptr){
                    int s = l1->val+carry;
                    ListNode* node = new ListNode(s%10);
                    carry = s/10;
                    curNode->next = node;
                    curNode = node;
                    l1 = l1->next;
                }
            }
            if(l1==nullptr && l2==nullptr){ // 看最后有没有进位比如[1]+[9],有的话加上
                if(carry!=0){   //有进位
                    ListNode* node = new ListNode(carry);
                    curNode->next = node;
                }
            }
            return head->next;
        }
    };
    
    • 时间复杂度:O(n)
    • 空间复杂度:O(n)
      链表所占的额外存储空间与输入的数据规模线性相关。

    更简洁的代码
    上面的代码可以写得更简洁,如下:

    /**
     * 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;
            }
    
    
            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;
            }
            return head->next;
        }
    };
    

    两种写法的时间空间复杂度是一样的。

    总结

    在模拟整数相加的时候,假设当前两个数相加为s,则s/10表示进位,s%10表示当前加的结果。

  • 相关阅读:
    个人总结05
    微软拼音的用户体验
    个人总结04
    典型用户和用户场景模式
    个人总结03
    个人总结02
    构建之法阅读笔记06
    个人总结01
    学习进度条——第七周
    WebApi学习总结系列第五篇(消息处理管道)
  • 原文地址:https://www.cnblogs.com/flix/p/12671988.html
Copyright © 2020-2023  润新知