【LeetCode】第2题:两数相加

题目描述

给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

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

示例1

addtwonumber1.jpeg

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

示例2

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

示例3

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

提示

  • 每个链表中的节点数在范围 [1, 100] 内
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零

思路

做题之前最重要的事情是看题目的提示,提示中会给出一些有关题目的限制条件。本题的限制条件有3个,第一个规定了链表节点数的范围,最少都是1个。节点的值在0到9之间,所以最大的两个数9+9=18,进位最多只能是1,有可能是0。题目给出的测试数据保证了不会出现前导0的情况。

这道题考察单链表的遍历操作,特别是要注意处理空指针和进位问题,最容易出错的地方时当遍历结束后,要注意如果进位为1,那么还要额外处理一下最后一个节点,别忘记了。我写的第一版算法如下:

func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
    result := &ListNode{0, nil}
    ptr1, ptr2, next := l1, l2, result
    carry := 0
    for ptr1 != nil && ptr2 != nil {
        next.Val = ptr1.Val + ptr2.Val + carry
        if next.Val >= 10 {
            carry = 1
            next.Val -= 10
        } else {
            carry = 0
        }
        ptr1 = ptr1.Next
        ptr2 = ptr2.Next
        if carry == 1 || ptr1 != nil || ptr2 != nil {
            next.Next = &ListNode{0, nil}
            next = next.Next
        }   
    }

    var ptr *ListNode
    if ptr1 != nil {
        ptr = ptr1
    } else {
        ptr = ptr2
    }
    
    if ptr == nil && carry == 1 {
        next.Val += carry
        if next.Val >= 10 {
            next.Val -= 10
            next.Next = &ListNode{1, nil}
        }
    } else {
        for ptr != nil {
            next.Val = ptr.Val + carry
            if next.Val >= 10 {
                carry = 1
                next.Val -= 10
            } else {
                carry = 0
            }
            ptr = ptr.Next
            if ptr != nil {
                next.Next = &ListNode{0, nil}
                next = next.Next
            }
        }
        if carry == 1 {
            next.Next = &ListNode{1, nil}
        }
    }
    
    return result
}

后来看了官方题解,发现人家的方法和我一样但写的比我简洁,我就重新试着写了一下:

func addTwoNumbers(l1 *ListNode, l2 *ListNode) (result *ListNode) {
    ptr1, ptr2, next := l1, l2, result
    value, carry := 0, 0

    for ptr1 != nil || ptr2 != nil {
        sum := carry
        if ptr1 != nil {
            sum += ptr1.Val
            ptr1 = ptr1.Next
        }
        if ptr2 != nil {
            sum += ptr2.Val
            ptr2 = ptr2.Next
        }

        value, carry = sum % 10, sum / 10
        if result == nil {
            next = &ListNode{value, nil}
            result = next
        } else {
            next.Next = &ListNode{value, nil}
            next = next.Next
        }
    }
    
    if carry == 1 {
        next.Next = &ListNode{carry, nil}
    }
    return
}

你可能感兴趣的:(【LeetCode】第2题:两数相加)