【LeetCode题解】2_两数相加

【LeetCode题解】2_两数相加

描述

给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。

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

示例:

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

方法一:小学数学

思路

按照小学数学中求两数之和的做法,从最低位(链表表头)开始加起,用变量 carry 保存进位的结果(初始值为0),每次求和之后更新变量 carry 的值。

Java 代码(非递归写法)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummyHead = new ListNode(-1);
        ListNode curNode = dummyHead, p = l1, q = l2;
        int carry = 0;
        
        while (p != null || q != null) {
            int x = (p != null) ? p.val : 0;
            int y = (q != null) ? q.val : 0;
            int sum = x + y + carry;
            carry = sum / 10;
            curNode.next = new ListNode(sum % 10);
            curNode = curNode.next;

            if (p != null) {
                p = p.next;
            }
            if (q != null) {
                q = q.next;
            }
        }

        if (carry > 0) {
            curNode.next = new ListNode(carry);
        }

        return dummyHead.next;
    }
}
// Runtime: 38 ms
// Your runtime beats 46.06 % of java submissions.

复杂度分析:

  • 时间复杂度:\(O(max(m, n))\),其中 \(m\)\(n\) 分别表示两个链表的长度。
  • 空间复杂度:\(O(max(m, n))\),返回链表的长度最多为 \(max(m, n) + 1\)

Java 代码(递归写法)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        return addTwoNumbers(l1, l2, 0);
    }

    private ListNode addTwoNumbers(ListNode l1, ListNode l2, int carry) {
        // Recursive termination condition
        if (l1 == null && l2 == null) {
            return carry > 0 ? new ListNode(carry) : null;
        }

        int sum = carry;
        ListNode l1Next = null, l2Next = null;
        if (l1 != null) {
            sum += l1.val;
            l1Next = l1.next;
        }
        if (l2 != null) {
            sum += l2.val;
            l2Next = l2.next;
        }
        ListNode curr = new ListNode(sum % 10);
        curr.next = addTwoNumbers(l1Next, l2Next, sum / 10);
        return curr;
    }
}
// Runtime: 27 ms
// Your runtime beats 94.02 % of java submissions.

复杂度分析同上。

Python 代码(非递归写法)

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

class Solution:
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
 		dummy_head = ListNode(-1)
 		cur = dummy_head
 		carry = 0

 		while l1 or l2 or carry:
 			v1 = v2 = 0
 			if l1:
 				v1 = l1.val
 				l1 = l1.next
			if l2:
				v2 = l2.val
				l2 = l2.next
			carry, val = divmod(v1 + v2 + carry, 10)
			cur.next = ListNode(val)
			cur = cur.next
		return dummy_head.next
    
# Runtime: 156 ms
# Your runtime beats 43.08 % of python3 submissions.

复杂度分析同上。

posted @ 2018-10-11 15:56  xugenpeng  阅读(387)  评论(0编辑  收藏  举报