【LeetCode】2. Add Two Numbers 解题报告(Python & C++)

作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


目录

    • 题目描述
    • 题目大意
    • 解题方法
      • 偷懒做法
      • 模拟加法
      • 递归解法
    • 日期

题目地址:https://leetcode.com/problems/add-two-numbers/description/

题目描述

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Example:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.

题目大意

有两个链表,分别是逆序了的十进制数字。现在要求两个十位数字的和,要求返回的结果也是链表。

解题方法

偷懒做法

先求和,再构建链表。这个方法比较暴力。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        num1 = ''
        num2 = ''
        while l1:
            num1 += str(l1.val)
            l1 = l1.next
        while l2:
            num2 += str(l2.val)
            l2 = l2.next
        add = str(int(num1[::-1]) + int(num2[::-1]))[::-1]
        head = ListNode(add[0])
        answer = head
        for i in range(1, len(add)):
            node = ListNode(add[i])
            head.next = node
            head = head.next
        return answer

模拟加法

根据官方solution的方法,可以采用一个进位carry方便的完成一次遍历得出结果,不过过程稍微麻烦。

两个要注意的地方:如果列表长度不相等;如果列表相加完成最后仍有进位位。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        head = ListNode(0)
        answer = head
        carry = 0
        while l1 and l2:
            add = l1.val + l2.val + carry
            carry = 1 if add >= 10 else 0
            head.next = ListNode(add % 10)
            head = head.next
            l1, l2 = l1.next, l2.next
        l = l1 if l1 else l2
        while l:
            add = l.val + carry
            carry = 1 if add >= 10 else 0
            head.next = ListNode(add % 10)
            head = head.next
            l = l.next
        if carry:
            head.next = ListNode(1)
        return answer.next

使用C++代码如下,这里在while循环中做了判断,如果l1,l2,carry等有一个存在那么就在后面继续添加节点,如果l1或者l2不存在就把它的值当做0处理。需要注意的是,下面的代码做了new操作,但是没有释放dummy指针,造成了内存泄露,虽然刷题能过,但是面试的时候应该会被面试官怼。C++需要自己管理内存,当需要new操作的时候,还是小心为妙啊!

/**
 * 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* dummy = new ListNode(0);
        ListNode* cur = dummy;
        int carry = 0;
        while (l1 || l2 || carry) {
            int target = (l1 ? l1-> val : 0) + (l2 ? l2-> val : 0) + carry;
            if (target >= 10) {
                carry = 1;
                target -= 10;
            } else 
                carry = 0;
            cur->next = new ListNode(target);
            cur = cur->next;
            if (l1)
                l1 = l1->next;
            if (l2)
                l2 = l2->next;
        }
        return dummy->next;
    }
};

递归解法

这个题的递归解法也是非常好玩的,如果两个链表节点都存在的话,把两个节点的值相加并且模10作为当前的结果,同时如果这个结果>=10需要把它的next节点+1.

这个解法妙在天然地处理好了两个链表不一样长、最终相加结果有进位的情况。

/**
 * 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) return l2;
        if (!l2) return l1;
        int target = l1->val + l2->val;
        ListNode* res = new ListNode(target % 10);
        res->next = addTwoNumbers(l1->next, l2->next);
        if (target >= 10)
            res->next = addTwoNumbers(res->next, new ListNode(1));
        delete l1, l2;
        return res;
    }
};

日期

2018 年 2 月 26 日
2019 年 1 月 11 日 —— 小光棍节?

你可能感兴趣的:(LeetCode,算法)