2 两数相加(2021-03-14)

2. 两数相加

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/add-two-numbers/

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

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

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

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

感想

我一定是一个傻逼,弱智,不看题解根本做不出来。

辅助函数

本地调试链表,需要添加几个辅助函数,帮助调试:

function ListNode(val, next) {
    this.val = val === undefined ? 0 : val;
    this.next = next === undefined ? null : next;
}

function arrToListNode(arr) {
    const head = new ListNode();
    let cur = head;
    while (arr.length) {
        const temp = arr.shift();
        cur.val = temp;
        if (arr.length) {
            cur.next = new ListNode();
            cur = cur.next;
        }
    }
    return head;
}

function listNodeToArr(node) {
    const result = [];
    while (node) {
        result.push(node.val);
        node = node.next;
    }
    return result;
}

分析

为什么做不出来,除了智商低之外,还是对链表太不熟悉

(1)如何声明一个链表

可以直接使用提供过的ListNode类,完成链表的初始化。同时需要声明一个headtail指针,最终返回的是head,而tail用来指明下一个节点,让链表随着迭代逐步后移,添加后续的变量

最后返回的应该是head,来代表整个链表

(2)已有链表如何向下逐步迭代

比如现在有一个链表l1,需要逐步迭代,最基本的结构应该是:

while (l1) {
    console.log(l1.val);
    l1 = l1.next;
}

(3)实现两数相加

上面都是关于链表的基础通用知识,关于这道题,最关键的在于链表的数字都是按照逆序排列的,所以求和时就可以直接相加,不存在需要反转后再相加的问题

另外,相加之后,需要一个临时变量carry来记录进位值,并且需要随着迭代这个carry不断更新,迭代完成后,如果carry不为0,那么就需要为tail添加最后一个节点

答案

var addTwoNumbers = function (l1, l2) {
  let head = (tail = null);
  let carry = 0;

  while (l1 || l2) {
    const n1 = l1 && l1.val ? l1.val : 0;
    const n2 = l2 && l2.val ? l2.val : 0;

    const sum = n1 + n2 + carry;
    const val = sum % 10;
    const node = new ListNode(val);

    if (!head) {
      head = tail = node;
    } else {
      tail.next = node;
      tail = tail.next;
    }

    carry = Math.floor(sum / 10);

    if (l1) {
      l1 = l1.next;
    }

    if (l2) {
      l2 = l2.next;
    }
  }

  if (carry) {
    tail.next = new ListNode(carry);
  }

  return head;
};

性能很差,运行时间144ms,只打败了58%的用户,一定有优化空间

重头再来

2022.09.23 公司里面移动端那个组在裁员了,感觉危机感更强了,还是要加深自己的基本功,那么的话,空闲的时候再刷刷题,增强算法,同时也挺有意思的

又做了一遍,基本上思路是一致的

var addTwoNumbers = function(l1, l2) {
    const result = new ListNode()
    let head = result;
    let carry = 0;

    while(l1 || l2) {
        const val1 = l1 && l1.val !== undefined ? l1.val : 0;
        const val2 = l2 && l2.val !== undefined ? l2.val : 0;

        const sum = val1 + val2 + carry;
        const value = sum % 10;
        carry = Math.floor(sum / 10);
        
        head.val = value;
      
        if (l1) {
            l1 = l1.next;
        }
        if (l2) {
            l2 = l2.next;
        }
        
        if (l1 || l2) {
            head.next = new ListNode();
            head = head.next;
        }
    }

    if (carry) {
       head.next = new ListNode(carry);
    }

    return result;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值