持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情
题目描述:
给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入: l1 = [2,4,3], l2 = [5,6,4]
输出: [7,0,8]
解释: 342 + 465 = 807.
解题思路:
循环遍历两个链表,计算每个节点相加的和,再加当前节点位置的进位值,然后计算进位。
-
循环依次取出两个链表的最低位(因为每位数字都是按照逆序的方式存储的,这个第一次的最低位就是输入数组的第一位);
-
依次求出最低位的和,和进位值相加,作为当前计算的值,
-
更新链表当前节点的位置(连接链表头和当前节点的值)
-
返回链表的值
function ListNode(val, next) {
this.val = val === undefined ? 0 : val
this.next = next === undefined ? null : next
}
var addTwoNumbers = function(l1, l2) {
// head 链表头 tail 链表当前节点位置
let head = null, tail = null;
//进位值
let carry = 0;
while (l1 || l2) {//循环l1,l2链表
// 链表中当前节点位置的值
const n1 = l1 ? l1.val : 0;
const n2 = l2 ? l2.val : 0;
const sum = n1 + n2 + carry;//当前计算的值:两链表节点相加,再加进位
if (!head) {
head = tail = new ListNode(sum % 10);//当没有节点的时候新建节点。%10是因为我们的计算结果是有可能大于10,所以需要取余
} else {
tail.next = new ListNode(sum % 10);//链表向下链接:有节点的时候则加入tail节点的后面
tail = tail.next;// 更新链表节点位置
}
carry = Math.floor(sum / 10);//求进位(满十进一)
if (l1) {//移动l1指针,指向下一个节点
l1 = l1.next;
}
if (l2) {//移动l2指针
l2 = l2.next;
}
}
//最后一位节点是否有进位
if (carry > 0) {
tail.next = new ListNode(carry);
}
return head;
};
知识点:链表
链表是由一些元素(节点)组成的集合,并且存储数据元素的内存空间可以连续,也可以不连续。每个节点(node)都由数据本身和一个指向后续节点的指针组成。
一个单链表 (SinglyLinkedList) 的节点(node)由以下几部分组成:
- 数据域(
data):保存数据 - 指针域(
next):保存“下一个节点地址”的指针
链表与数组的区别:
链表和数组都是线性数据结构。
数组:存储需要一块连续的内存空间,数组做增删或者插入操作,可能需要移动大量的元素。
链表:存储不需要一块连续的内存空间,通过“指针”将节点连接起来。增删元素,不需要移动元素,只需要改next的指向即可。