两数相加——链表的使用

152 阅读2分钟
  • 今天的每日一题: Add Two Numbers
  • 题目描述:给定两个用链表表示的非负数,链表的顺序与数字的高低位顺序相反,例如123对应的链表则是:3->2->1求两个数字之和,并以链表的形式给出结果.
  • eg:输入:3->2->1, 4->5->6,输出:7->7->7;
  • 结题思路:链表是常见的一种数据结构,一条长度为n的链表由n个链表节点组成,每个节点都保存有当前节点的值与指向后续节点的信息。由于链表的这一特点,导致我们不能像操作数组一样,随意取得数组中某一项的值。那么,我们可以首先将链表中表示的数转化为正常的数字:

节点构造函数:

const ListNode = (val,next)={
    this.val = !!val ? val : 0,
    this.next = !!next ? next : 0
}

链表转换为数字:

const convertListToNumber = (list)=>{
    let arr = [];
    while(list){
        arr.unshift(list.val);
        list = list.next;
    }
    return parseInt(arr.join(''))
}

通过covertListToNumber函数,我们可以将list链表表示的数字转化为我们熟悉的十进制数字。然后采用常规的十进制加法得到两数相加的结果,然后才使用convertNumberToList方法将结果转化为链表。

const convertNumberToList = (num)=>{
    let head = null; 
    let list = null;
    let carry = 0;
    const arr = num.toString().split('');
    const len = arr.length;
    for(let i = len - 1; i >= 0; i--){
        const sum = parseInt(arr[i]) + carry;
        carry = parseInt(sum / 10);
        const node = new ListNode(arr[i]);
        if(!head){
            head = node;
            list = head;
        }else{
            list.next = node;
            list= node
        }
    }
    return head
}

这种转换的方法确实可以在一定程度上解决我们的麻烦,但是当我们遇到更大的数字,两个数字中一个接近js Number类型表示的范围,我们就无法得到正确的结果。而且上述解法在代码效率上也有重大缺陷,我们首先是将两个list遍历,然后求和,再分解,在遍历生成链表,在整个过程中我们做了很多重复的工作。我们需要一种更优解。

  • 我们考虑直接对两个list循环,计算两数之和,代码如下:
const addTwoNumbers = (l1,l2)=>{
    let head = nul;
    let list = null;
    let carry = 0;
    let sum = 0;
    while(l1 || l2 || prev){
        sum += carry;
        if(!!l1){
            sum += l1.val;
            l1 = l1.next;
        }
        if(!!l2){
            sum += l2.val;
            l2 = l2.next;
        }
        const node = new ListNode(sum%10);
        carry = parseInt(sum/10);
        if(!head){
            head = node;
            list = head;
        }else{
            list.next = node;
            list = node
        }
    }
    return head;
}

第二种方法在效率上相对第一种更高,简化掉许多不必要的重复计算,同时也能很好的处理大数问题。

好了,这就是今天的LeetCode每日一题。鉴于本人水平有限,欢迎指正赐教!

雄关漫道真如铁, 而今迈步从头越。