LeeCode 002-两数相加
博主是一个前大厂前端开发,以后会不定期更新前端知识,和算法分享~
题目地址:https://leetcode.cn/problems/add-two-numbers/description/
概述:
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
思路1(错误解法)
做题少的小伙伴,拿道题的第一想法可能是将两个链表遍历组成数字,相加得到结果,再将结果转换为目标链表,我将按照这个思路写一遍。(出现的问题详见下述结果)
/**
* 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 v1 = l1.val;
let v2 = l2.val;
let p1 = l1;
let p2 = l2;
// 遍历两个链表 依次得到目标求和数字
while(p1.next !=null){
// 由于链表是由个位开始,所以后出现的数字放在前面
v1 = p1.next.val.toString()+v1.toString()
p1 = p1.next
}
while(p2.next !=null){
// v2 = v2+ p2.next.val*Math.pow(10,(v2.toString().length))
v2 = p2.next.val.toString()+v2.toString()
p2 = p2.next
}
// 得到求和结果res
let res = (+v1+ +v2).toString()
let result = new ListNode()
let resultTemp = new ListNode()
// 遍历结果,放进链表中
for(let i = 0;i<res.length;i++){
let node = new ListNode(res[res.length-i-1])
if (i === 0) {
result =node // 新节点成为头节点
resultTemp = result; // 当前节点指向头节点
} else {
// 将当前节点的下一个节点设置为新节点
resultTemp.next = node;
// 当前节点移到下一个位置
resultTemp = resultTemp.next;
}
}
return result;
};
提交答案结果:
显然,这种两数相加的方式会超过js的默认运算范围,至此明白题意应该是让我们模拟相加运算的法则,通过算法模拟由个位逐级相加进位的运算。
思路2(模拟相加运算)
两个链表均是由个位开始,因此大致思路为同时遍历两个链表,逐位求和,若有进位则记录,下一位运算时相加,短的链表先结束,则长链表剩下的数字都是高位,直接遍历加入结果链表即可。(譬如:9+100 = 109 》 9 + 001 = 901 ,这里100中的01就是高位,直接遍历即可)
详见注释
/**
* 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) {
// 初始没有进位,置为0
let carry = 0
// res表示结果链表,cur则是当前遍历指针
let res =null, cur = null
while(l1 !==null || l2!==null){
const n1 = l1 ? l1.val : 0;
const n2 = l2 ? l2.val : 0;
const sum = n1 + n2 + carry;
if(res ==null){
// 若为第一次相加
res = cur = new ListNode(sum % 10)
}else{
// 每次追加至链表的结果是模10的结果,因为一旦和大于10就要进位,不能直接置为sum
//(譬如9+6=15,应该置为5,进位1)
cur.next = new ListNode(sum % 10)
cur = cur.next
}
// 更新每次运算的进位,不大于10则结果为0,表示不进位
carry = Math.floor(sum / 10)
// 两个链表进位
if(l1){
l1 = l1.next
}
if(l2){
l2 = l2.next
}
}
// 如果最后一次运算有进位,不要忘记追加
if(carry > 0){
cur.next = new ListNode(carry)
}
return res;
};
至此完结,喜欢本文的观众大大记得点赞关注哦~
博主是一个前大厂前端开发,以后会不定期更新前端知识,和算法分享~