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
类,完成链表的初始化。同时需要声明一个head
和tail
指针,最终返回的是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;
};