leetCode Add Two Numbers

来源:互联网 发布:大数据课程培训大纲 编辑:程序博客网 时间:2024/06/06 06:41

问题网址:[https://leetcode.com/problems/add-two-numbers/description/]

问题描述:
给定两个非空的链表,表示两个非负整数。 数字以相反的顺序存储,每个节点包含一个数字。 将两个数字的和作为链表返回。

假设两个数字不包含任何前导零,除了数字0本身。

问题样例:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)Output: 7 -> 0 -> 8

直觉想法:
使用变量跟踪进位,并从包含最低有效数字的列表头开始模拟数位数字和。
由于数字是反序存储的,是相加变得更加容易。

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {    ListNode* head = nullptr;    ListNode* tail = nullptr;     int result;    int carry;    while (l1 && l2) {        if (head == nullptr) {            result = (l1->val + l2->val) % 10;            carry = (l1->val + l2->val) / 10;            head = new ListNode(result);            tail = head;        } else {            result = (l1->val + l2->val + carry) % 10;            carry = (l1->val + l2->val + carry) / 10;            ListNode* next = new ListNode(result);            tail->next = next;            tail = next;        }        l1 = l1->next;        l2 = l2->next;    }    while (l1) {        if (head == nullptr) {            head = new ListNode(l1->val);            tail = head;        } else {            result = (l1->val + carry) % 10;            carry = (l1->val + carry) / 10;            ListNode* next = new ListNode(result);            tail->next = next;            tail = next;        }        l1 = l1->next;     }    while (l2) {        if (head == nullptr) {            head = new ListNode(l2->val);            tail = head;        } else {            result = (l2->val + carry) % 10;            carry = (l2->val + carry) / 10;            ListNode* next = new ListNode(result);            tail->next = next;            tail = next;        }        l2 = l2->next;    }    if (carry) {        ListNode* next = new ListNode(1);        tail->next = next;        tail = next;    }    return head;}

时间复杂度:O(n)

优化的想法:
初始化返回链表
初始化进位为0。
通过列表l1和l2循环,直至到达两端。
将x设置为节点l1的值。如果l1为空,则设为0。
将y设置为节点l2的值。如果l2为空,则设为0。
设置和sum = x + y + carry。
更新进位carry= sum / 10。
创建一个值为(sum mod 10)的新节点,并将其设置为当前节点的下一个节点,然后将当前节点推送到下一个节点。
推进l1和l2。
检查进位carry = 1,如果这样,将数字1的新节点附加到返回列表。
返回头节点的下一个节点。
需要注意的是,我们使用不存储值的头节点来简化代码。如果没有这个头街头,我们将不得不编写额外的条件语句来初始化头的值。这个技巧在链表处理中比较常用。

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {    ListNode* head = new ListNode(0);    ListNode* current = head;    int carry = 0;    while (l1 || l2) {        int sum = carry + (l1 ? l1->val : 0) + (l2 ? l2->val : 0);        carry = sum / 10;        current->next = new ListNode(sum % 10);        current = current->next;        if (l1) l1 = l1->next;        if (l2) l2 = l2->next;    }    if (carry > 0) {        current->next = new ListNode(1);    }    return head->next;}

时间复杂度:O(n)