小目标 To be or not to be

Leetcode 002 Add two numbers

2017-02-22
chaowyc

Leetcode 002 题

Difficulty:Medium

Tag: Linked List, Math

Add two numbers

大致题意

原题目链接 : https://leetcode.com/problems/add-two-numbers/?tab=Description

给定两个链表,每个链表都表示一个非负整数,这个整数数的每一位都是按照逆序存储在链表的节点上,且每个节点只能存储一个位信息。

比如

整数 342,用这种链表表示应该是 2 -> 4 -> 3 。

例子

两个链表分别表示整数 342 和 475. 根据题意

链表 ( l_1: 2 -> 4 -> 3 )

链表 $ l_2: 4 -> 7 -> 5 $

两数相加的结果为

$ 7 -> 1 -> 8 $

解析

这其实一个两个链表相加的问题,只不过进位需要向右传播。

image

如上图所示: 依次计算每一位,由于有进位的存在,所以还要加上前一位的进位:

计算过程如下:

第一位 $ result_0 = 2 + 5 + carry_0 (carry_0 = 0) $

进位 $ carry_1 = result_0 / 10$

第二位 $ result_1 = 2 + 5 + carry_1 $

进位 $ carry_2 = result_1 / 10$

第三位 $ result_2 = 2 + 5 + carry_2 $

进位 $ carry_1 = result_2 / 10$

明显是一个迭代算法,每次迭代更新 result 和 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) {
        ListNode result(0);
        ListNode* p = &result;
        int carry = 0;
        while(l1 || l2)
        {
            int res = carry + (l1 ? l1->val : 0) + (l2 ? l2->val : 0);
            carry = res / 10;
            res = res % 10;
            p->next = new ListNode(res);
            p = p->next;
            if(l1) l1 = l1->next;
            if(l2) l2 = l2->next;
        }
        if(carry)
        {
            p->next = new ListNode(carry);
            p = p->next;
        }
        return result.next;
    }
};

时间复杂度

整段程序只有一个while循环,所以是线性的时间复杂度 $O(n)$.

具体的值:假设 $m$和$ n $ 分别为$l_1$, $l_2$的长度,while循环执行的次数取决于 $m$和$ n $ 最大的那个,时间复杂大具体为 $O(max(m, n))$


Similar Posts

Comments