LeetCode 两数相加

1,125 阅读2分钟

题目

  • 给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。

  • 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 您可以假设除了数字 0 之外,这两个数都不会以0开头。

  • 示例:

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

题目链接

分析

  • 输入的是两个链表
  • 链表的顺序是数字的倒序,且每个节点存一位数字
  • 两个链表的长度不一定相同
  • 输出的结果为两数相加后和的倒序
  • 每个位相加后有可能进位即(l1.val + l2.val + param(进位值:0 | 1)),最小值(0 + 0 + 0),最大值(9 + 9 + 1)

解题思路

  • 遍历两个链表,将相同的每个位置数相加后组成一个相加结果的倒序字符串;注意处理特殊情况,可以快速得到特殊情况的结果,例如:链表一或者链表二为空的情况;注意判断临界条件,例如:链表一或者链表二结束时(list.next === null)
  1. 声明初始的变量
let x = l1, // 链表一的首位
    y = l2, // 链表二的首位
    param = 0, // 进位值
    value = ''; // 结果字符串
  1. 判断特殊情况
if ( !l1 ) return l2
if ( !l2 ) return l1
  1. 同时循环两个链表
while(x || y) {
    let xV = x ? x.val : 0; // 链表一是否结束,结束用0补位
    let yV = y ? y.val : 0; // 链表二是否结束,结束用0补位
    value += ( xV + yV + param) % 10 // 获取当前位的值
    param = parseInt( ( xV + yV + param ) / 10, 10 ) // 获取进位值
    if (x) x = x.next // 判断链表一是否结束
    if (y) y = y.next // 判断链表二是否结束
}
  1. 循环完之后判断param进位是否位0,不为0,追加到value之后
if( param ) value += param
  1. 处理value,并返回目标结果
let node = { // 创建节点
    val: null,
    next: null
},
head = node;
value.split('').forEach(item => {
    node.next = {
        val: parseInt(item,10), // 字符串split后得到的是字符,所以需要转成数字number类型
        next: null
    }
    node = node.next;
})
return head.next; 
  1. 全部代码
/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function(l1, l2) {
    let x = l1,
        y = l2,
        param = 0, // 进位值
        value = '';
    if ( !l1 )return l2
    if ( !l2 ) return l1
    while(x || y) {
        let xV = x ? x.val : 0;
        let yV = y ? y.val : 0;
        value += ( xV + yV + param) % 10
        param = parseInt( ( xV + yV + param ) / 10, 10 )
        if (x) x = x.next
        if (y) y = y.next
    }
    if( param ) value += param
    let node = {
        val: null,
        next: null
    },
    head = node;
    value.split('').forEach(item => {
        node.next = {
            val: parseInt(item,10),
            next: null
        }
        node = node.next;
    })
    return head.next; 
};

总结

  • 数字的操作,需要多考虑临界条件,相加的进位、相减的借位等等
  • 链表的遍历,考虑是否为空,是否已到尾部
  • 本题的解法不唯一,欢迎共同探讨学习