链表系列之数字相加,整数溢出解决方案!

156 阅读2分钟

题目

image.png

解析

  • 这道题其实最暴力的解法就是直接遍历两个链表然后去得到两个整数,将这两个整数相加的结果转化为链表
  • 但是这样做有个问题:整数有可能会溢出
  • 最好的解决方案是节点与节点的相加,并实时的转换为链表

解法

function addList(list1, list2) {
    // 利用反转后再相加比较好处理相加大于10的情况
    let reverse1 = reverseList(list1)
    let reverse2 = reverseList(list2)

    return helper(reverse1, reverse2)
}

console.log(addList(head1, head2)); // 打印结果

// 反转链表就是记录三个变量
function reverseList(listNode) {
    let pre = null; // 前一个
    let cur = listNode; // 现在
    let next = listNode.next // 下一个

    while(cur !== null) {
        next = cur.next // 在反转的时候注意记录先下一个节点
        cur.next = pre;
        pre = cur;
        cur = next;
    }

    return pre;
}

function helper(rev1, rev2) {
    let sum = 0;
    let head = new listNode(0, null)
    let next = head
    
    // 两个链表不一定是等长的,所以对rev1、2的取值要做特殊判断
    while(rev1 || rev2) {
        // 如果是 null 的情况就默认为 0
        sum = (rev1 ? rev1.val : 0) + (rev2 ? rev2.val : 0) // 已经遍历完就默认为0
        
        if (sum > 10) {
            next.val = sum - 10;
            next.next = new listNode(1, null)
        } else {
            next.val += sum

            // 最后一次的叠加小于 10 是一个无用节点要去掉,因为不用再开辟新的节点继续遍历了
            next.next = new listNode(0, null) 
        }
        
        next = next.next
        
        // 已经遍历完就默认为原来的值避免报错
        rev1 = rev1 ? rev1.next : rev1;
        rev2 = rev2 ? rev2.next : rev2;
    }

    const temp = reverseList(head)

    if (temp.val) return temp;
    return temp.next;  // 去掉无用节点
}

附带测试用例 tips:312 + 612 = 924

class listNode {
    constructor(val, next) {
        this.val = val;
        this.next = next;
    }
}

const head1 = new listNode(3, null)
let next = head1

for (let i = 1; i < 3; i++) {
    next.next = new listNode(i, null)
    next = next.next
}

const head2 = new listNode(6, null)
let next2 = head2

for (let i = 1; i < 3; i++) {
    next2.next = new listNode(i, null)
    next2 = next2.next
}

function addList(list1, list2) {
    // 利用反转后再相加比较好处理相加大于10的情况
    let reverse1 = reverseList(list1)
    let reverse2 = reverseList(list2)

    return helper(reverse1, reverse2)
}

console.log(addList(head1, head2)); // 打印结果

// 反转链表就是记录三个变量
function reverseList(listNode) {
    let pre = null; // 前一个
    let cur = listNode; // 现在
    let next = listNode.next // 下一个

    while(cur !== null) {
        next = cur.next // 在反转的时候注意记录先下一个节点
        cur.next = pre;
        pre = cur;
        cur = next;
    }

    return pre;
}

function helper(rev1, rev2) {
    let sum = 0;
    let head = new listNode(0, null)
    let next = head
    
    // 两个链表不一定是等长的,所以对rev1、2的取值要做特殊判断
    while(rev1 || rev2) {
        // 如果是 null 的情况就默认为 0
        sum = (rev1 ? rev1.val : 0) + (rev2 ? rev2.val : 0) // 已经遍历完就默认为0
        
        if (sum > 10) {
            next.val = sum - 10;
            next.next = new listNode(1, null)
        } else {
            next.val += sum

            // 最后一次的叠加小于 10 是一个无用节点要去掉,因为不用再开辟新的节点继续遍历了
            next.next = new listNode(0, null) 
        }
        
        next = next.next
        
        // 已经遍历完就默认为原来的值避免报错
        rev1 = rev1 ? rev1.next : rev1;
        rev2 = rev2 ? rev2.next : rev2;
    }

    const temp = reverseList(head)

    if (temp.val) return temp;
    return temp.next;  // 去掉无用节点
}