全栈开发知识库

58.两数相加

题目

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

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

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

示例:

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

示例 2:

  • 输入:l1 = [0], l2 = [0]
  • 输出:[0]

示例 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
  • 题目数据保证列表表示的数字不含前导零

思路

题目说每个节点的值都在0~9里面,所以只考虑个位数就好。

2 -> 4 -> 3  表示 342
5 -> 6 -> 4  表示 465
---------------------
7 -> 0 -> 8  表示807

其实就是模拟小学竖式加法,先从个位开始逐位相加,记住进位。

3  4  2
4  6  5
-------
8  0  7

每一位: 当前位的值 = (l1当前位的值 + l2当前位的值 + 进位) % 10

进位: carry = (l1当前位的值 + l2当前位的值 + 进位) / 10

class Solution {
    fun addTwoNumbers(l1: ListNode?, l2: ListNode?): ListNode? {
        var l1NodeIndex = l1
        var l2NodeIndex = l2
        // 进位
        var carry = 0
        // 头结点
        var head: ListNode? = null
        // 记录当前节点
        var curr: ListNode? = null

        while (l1NodeIndex != null || l2NodeIndex != null || carry != 0) {
            val sum = (l1NodeIndex?.`val` ?: 0) + (l2NodeIndex?.`val` ?: 0) + carry
            carry = sum / 10
            val node = ListNode(sum % 10)

            if (head == null) {
                head = node
                curr = node
            } else {
                curr!!.next = node
                curr = node
            }

            l1NodeIndex = l1NodeIndex?.next
            l2NodeIndex = l2NodeIndex?.next
        }

        return head
    }

    class ListNode(var `val`: Int) {
        var value: Int = 0
        var next: ListNode? = null
    }
}

复杂度

  • 时间复杂度:O(max(m,n)):m、n 是两个链表的长度,最多遍历较长的那个。
  • 空间复杂度:O(max(m,n)):结果链表的长度最多是 max(m,n)+1。


  • 邮箱 :charon.chui@gmail.com
  • Good Luck!
本页由 Markdown 自动渲染 · 共 628 篇笔记