05. 解密前端算法题:两数相加

题目
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:
输入:l1 = [2,4,3], l2 = [5,6,4] 输出:[7,0,8] 解释:342 + 465 = 807.
提示:
- 每个链表中的节点数在范围
[1, 100]内 0 <= Node.val <= 9- 题目数据保证列表表示的数字不含前导零
这是官方构造函数:
function ListNode(val, next) {
this.val = val === undefined ? 0 : val
this.next = next === undefined ? null : next
}
示例中的 l1 = [2,4,3], l2 = [5,6,4] 可以这样造出来:
var a = new ListNode(3) var b = new ListNode(4, a) var c = new ListNode(2, b) var l1 = c var d = new ListNode(4) var e = new ListNode(5, a) var f = new ListNode(6, b) var l2 = f
解题思路
以本题的例题为例:(2->4->3)+(5->6->4) = (7->0->8),根据加法的计算过程我们知道首先从低位开始算起,也就是说应该先计算 2+5=7,所以思路来了:
1. 首先取出“+”左右两边两个数的最低位,也就是:
let val1 = l1.val let val2 = l2.val
2. 其次求出他们的和并作为输出结果的最低位(由于输出的结果是链表的形式保存,所以我们应该写成这种形式)
let sum = new ListNode('0')
sum.next = new ListNode(“结果” % 10)
//之所以要“结果” % 10 是因为我们的计算结果是有可能大于 10 的,所以需要取余
所以初步的代码如下:
var addTwoNumbers = function(l1, l2) {
let sum = new ListNode('0') // 创建一个头链表用于保存结果
let head = sum // 保存头链表的位置用于最后的链表返回
while (l1 || l2) {//在两个链表之中有一个存在的前提下执行下面的逻辑
let val1 = l1.val
let val2 = l2.val
let r1 = val1 + val2//求和
sum.next = new ListNode(r1 % 10)//sum 的下一个节点
sum = sum.next //sum 指向下一个节点
if (l1) l1 = l1.next //l1 指向下一个节点,以便计算第二个节点的值
if(l2) l2 = l2.next //l2 指向下一个节点,以便计算第二个节点的值
}
return head.next //返回计算结果,之所以用 head.next 是因为 head 中保存的第一个节点是刚开始定义的“0”
};
3. 下面便是开始进行优化了,我们应该知道的第一点是加法运算是有进位的,所以考虑将进位加入代码中:
var addTwoNumbers = function(l1, l2) {
let addOne = 0 //进位
let sum = new ListNode('0')
let head = sum
while (addOne || l1 || l2) {//在进位或者两个链表之中有一个存在的前提下执行下面的逻辑
let val1 = l1.val
let val2 = l2.val
let r1 = val1 + val2 + addOne//求和
addOne = r1 >= 10 ? 1 : 0 // 如果求和结果>=10,那么进位为 1,否则为 0
sum.next = new ListNode(r1 % 10)
sum = sum.next
if (l1) l1 = l1.next
if(l2) l2 = l2.next
}
return head.next
};
4. 能写出以上代码已经接近成功了,但是离成功还差个那么一步,当我们提交的时候并不能通过所有的案例,不能通过的一个案例为:[9999] 与 [99] 相加,这是因为 l1 与 l2 相加的过程中,当指针指向第三个 9 的时候 l1 的 9 是存在的而 l2 的 9 是不存在的,也就是为 null,所以无法相加会进行报错,所以我们需要进行一步优化,如果值不存在时,将其设置为 0,然后再进行相加即可,完成代码如下:
var addTwoNumbers = function(l1, l2) {
let addOne = 0
let sum = new ListNode('0')
let head = sum
while (addOne || l1 || l2) {
let val1 = l1 !== null ? l1.val : 0 // 优化点
let val2 = l2 !== null ? l2.val : 0 //优化点
let r1 = val1 + val2 + addOne
addOne = r1 >= 10 ? 1 : 0
sum.next = new ListNode(r1 % 10)
sum = sum.next
if (l1) l1 = l1.next
if (l2) l2 = l2.next
}
return head.next
};
这个解法是最直接的最通用的,以后无论多少个数相加都可以采用这种思路。
附上完整代码:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var addTwoNumbers = function(l1, l2) {
let addOne = 0
let sum = new ListNode('0')
let head = sum
while (addOne || l1 || l2) {
let val1 = l1 !== null ? l1.val : 0
let val2 = l2 !== null ? l2.val : 0
let r1 = val1 + val2 + addOne
addOne = r1 >= 10 ? 1 : 0
sum.next = new ListNode(r1 % 10)
sum = sum.next
if (l1) l1 = l1.next
if (l2) l2 = l2.next
}
return head.next
};
力扣原题连接:点击这里
以上关于05. 解密前端算法题:两数相加的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » 05. 解密前端算法题:两数相加
微信
支付宝