LeetCode 热题 HOT — 两数相加

143 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

两数相加

原题地址

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

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

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

示例 1:

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

思路分析

方法一

  1. 首先将两个链表转换成数字,转换数字的方法为 getNums,先转换成数组后在翻转转换成数字;
  2. 两个数字进行相加后,由相加后的数字转换成新的链表,即为返回的最终结果;
  3. 在最终提交运行的时候,卡在了第 1565 个用例,排查后发现在数字转换时,太大的数字会转成科学计数法的方式展示,因此相加运算会有问题。搜索有没有什么办法可以保证 js 中的数字不转换成科学计数法,但是没有找到合适的方法。因此需要另外考虑,当然,本题设计的初衷应该也不是使用这么迂回的方式解决。

方法二

  1. 因为链表是逆序存储,那么链表从 root 开始对应的值可以在同位置进行相加;
  2. 若该位置的 val 相加的结果大于 10,那么可以把进位放到 next 相加,若小于 10,那么进位为 0,定义 num 来存储进位;
  3. 遍历链表得到对应的结果。

AC 代码

方法一

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function(l1, l2) {
    const nums1 = getNums(l1)
    const nums2 = getNums(l2)
    const sum = (nums1 + nums2) + ''
    let res = new ListNode(sum[sum.length-1])
    let pre = res
    for(let i = sum.length - 2; i >= 0;i--){
        const node = new ListNode(sum[i])
        pre.next = node
        pre = node
    }
    return res
};

var getNums = function(l) {
    const arr = []
    while(l) {
        arr.push(l.val)
        l = l.next
    }
    return parseInt(arr.reverse().join(''))
}

结果:

  • 执行结果: 解答错误
输入:
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1] [5,6,4]
输出:
[0,3,NaN,NaN,1]
预期结果:
[6,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]

方法二

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function(l1, l2) {
    let res = new ListNode()
    let prev = res
    let num = 0
    while(l1 || l2) {
        const nums1 = l1 ? l1.val : 0
        const nums2 = l2 ? l2.val : 0
        const sum = nums1 + nums2 + num
        let node = null
        if(sum >= 10) {
            num = Math.floor(sum / 10)
            node = new ListNode(sum % 10)
        } else {
            num = 0
            node = new ListNode(sum)
        }
        prev.next = node
        prev = node
        if (l1) {
            l1 = l1.next;
        }
        if (l2) {
            l2 = l2.next;
        }
    }
    if (num > 0) {
        prev.next = new ListNode(num);
    }
    return res.next
};

结果:

  • 执行结果: 通过
  • 执行用时:80 ms, 在所有 JavaScript 提交中击败了98.84%的用户
  • 内存消耗:46.3 MB, 在所有 JavaScript 提交中击败了24.07%的用户
  • 通过测试用例:1568 / 1568

END