[路飞]_leetcode刷题_445. 两数相加 II

130 阅读2分钟

题目

445. 两数相加 II

给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。

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

示例1:

输入: l1 = [7,2,4,3], l2 = [5,6,4]
输出: [7,8,0,7]

思路1:

暴力解法,先把链表变成数字,再相加,再变成链表

/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function(l1, l2) {
    let str1 = '',str2='';
    if(l1.val == 0){
        str1 = '0'
    }
    if(l2.val == 0){
        str2 = '0'
    }
    while(l1){
        str1 += String(l1.val)
        l1 = l1.next;
    }
    while(l2){
        str2 += String(l2.val)
        l2 = l2.next;
    }
    let sum = String(Number(str1) + Number(str2));
    let arr = sum.split('');
    let dummy = new ListNode(0);
    let cur = dummy;
    for(let i=0;i<arr.length;i++){
        cur.next = new ListNode(arr[i]);
        cur = cur.next;
    }
    cur.next = null;
    return dummy.next;
};

但是,被制裁了,竟然搞个大数相加,科学计算法都出来了。。。。

image.png

好吧,老老实实想正经答案。

思路2:

先反转链表,然后遍历链表,以每一项相加的值创建新的节点,最后再将链表反转回来。

这里要注意判断相加值>10的时候,要进一位

代码如下:

/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function(l1, l2) {
    let revL1 = reverse(l1);
    let revL2 = reverse(l2);
    let dummy = new ListNode(0);
    let cur = dummy;
    let update = 0;
    let a1,a2;
    while(revL1 || revL2 || update>0){
        a1 = revL1 ? revL1.val : 0 ;
        a2 = revL2 ? revL2.val : 0;
        if((a1+a2+update)>=10){
            cur.next = new ListNode((a1 + a2 + update)%10)
            update = 1;
        }else{
            cur.next = new ListNode(a1 + a2 + update)
            update = 0;
        }
        cur = cur.next;
        revL1 = revL1 ? revL1.next : null;
        revL2 = revL2 ? revL2.next : null;
    }
    return reverse(dummy.next);
};


function reverse(head){
    let pre = null;
    let temp;
    while(head){
        temp = head.next;
        head.next = pre;
        pre = head;
        head = temp;
    }
    return pre;
}

思路3:

如果链表不让反转,其实我们可以用栈来代替,先用栈把l1和l2分别压入两个栈stack1和stack2,然后再依次pop取数相加,新增节点,判断大于10进一位的逻辑和上面思路2是一样的。

代码如下:

/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function(l1, l2) {
    let stack1 = [];
    let stack2 = [];
    while(l1){
        stack1.push(l1.val)
        l1 = l1.next;
    }
    while(l2){
        stack2.push(l2.val)
        l2 = l2.next;
    }
    let cur = null;
    let update = 0;
    let a1,a2,temp;
    while(stack1.length>0 || stack2.length>0 || update>0){
        a1 = stack1.length>0 ? stack1.pop() : 0 ;
        a2 = stack2.length>0 ? stack2.pop() : 0 ;
        if((a1+a2+update)>=10){
            temp = new ListNode((a1 + a2 + update)%10)
            update = 1;
        }else{
            temp = new ListNode(a1 + a2 + update)
            update = 0;
        }
        temp.next = cur;
        cur = temp;
    }
    return cur;
};

上面代码写的有些粗糙,很多判断都有点不精简,优化如下:

/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function(l1, l2) {
    let stack1 = [];
    let stack2 = [];
    while(l1){
        stack1.push(l1.val)
        l1 = l1.next;
    }
    while(l2){
        stack2.push(l2.val)
        l2 = l2.next;
    }
    let cur = null;
    let update = 0;
    let a1,a2,sum,temp;
    while(stack1.length>0 || stack2.length>0 || update>0){
        a1 = stack1.length>0 ? stack1.pop() : 0 ;
        a2 = stack2.length>0 ? stack2.pop() : 0 ;
        sum = a1 + a2 + update;
        update = Math.floor(sum/10)
        sum = sum % 10
        temp = new ListNode(sum)
        temp.next = cur;
        cur = temp;
    }
    return cur;
};