题目
这题考的就一个加法运算和进位,以及链表。
链表的实现就用了一个比较简单的构造函数ListNode,有val,next两个属性,多个ListNode通过next连起来形成链表。
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
扩展
这里题目输入的[2,4,3]/[5,6,4]看起来是数组其实应该是由ListNode连起来的链表,如下:
ListNode {
val: 2,
next: ListNode { val: 4, next: ListNode { val: 3, next: null } }
}
ListNode {
val: 5,
next: ListNode { val: 6, next: ListNode { val: 4, next: null } }
}
然后写了个转换的函数,如下:
/**
*
* @param {Array} arr
* @returns {ListNode}
*/
function createLink(arr) {
// 第一个节点和最后一个节点
let resNode, curNode;
while(arr.length){
let tempNode = new ListNode(arr.shift());
// 如果是第一个节点
if (!resNode) resNode = curNode = tempNode;
// 非第一个节点
else {
curNode.next = tempNode;
curNode = curNode.next;
};
}
return resNode;
}
思路一
很明显给到的链表的顺序和原数字的倒序,并且加法运算也是从个位开始计算,然后大于10的就进位,就是最基本的加法即可。
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
function addTwoNumbers(l1, l2) {
// 进位
let curry = 0;
// 第一个节点和最后一个节点
let resNode, curNode;
// 首先考虑链表长度,最后考虑是否有进位
while (l1 || l2 || curry !== 0) {
// 当前位置与进位相加
let sum = (l1 && l1.val || 0) + (l2 && l2.val || 0) + curry;
// 更新进位
curry = Math.floor(sum / 10);
// 当前位置
let tempNode = new ListNode(sum % 10);
// 如果是第一个节点
if (!resNode) {
resNode = curNode = tempNode;
}
// 非第一个节点
else {
curNode.next = tempNode;
curNode = curNode.next;
}
// 遍历链表
l1 = l1 ? l1.next : null;
l2 = l2 ? l2.next : null;
}
return resNode;
};
可以大致看到和上面的转换链表的函数相似,只是while循环的条件变为了链表节点,以及多了进位计算。
复杂度
空间复杂度:没使用与数据量相关的额外空间,O(1)
时间复杂度:要算的位数取决于两个数的最大值,假设两个链表长度分别为M,N,时间复杂度为O(Max(M,N))