描述
假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
给定两个这种链表,请生成代表两个整数相加值的结果链表。
数据范围:0 \le n,m \le 10000000≤n,m≤1000000,链表任意值 0 \le val \le 90≤val≤9
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)
例如:链表 1 为 9->3->7,链表 2 为 6->3,最后生成新的结果链表为 1->0->0->0。
示例1
输入:
[9,3,7],[6,3]
返回值:
{1,0,0,0}
说明:
如题面解释
示例2
输入:
[0],[6,3]
返回值:
{6,3}
思路: 这一题还是蛮难的,一开始判断这题的难点在js大数相加,解决掉大数相加之后,还是和之前使用的方法一样,先转为数组,用数组的方法再生成链表,但在第五组测试用例的时候超时了,于是乎明白了,这道题真正的难点在于性能。不论是我创建新的链表节点还是线性遍历,这些都需要花大量的时间,最好是在原链表的基础上改动,不生产新的链表。
解决解决思路:
1,将原链表反转,方便相加。
2,选择最长的链表遍历。
3,在遍历时相加的值赋给较长的链表,同时将该链表反转
4,如果最后一相和大于10,向前进一;
代码:
function ListNode(x){
this.val = x;
this.next = null;
}
// 反转链表
function reverse(node){
let len = 0,
pre = null,
temp = null;
while(node){
temp = node.next;
node.next = pre;
pre = node;
node = temp;
len += 1;
}
return {len, pre};
}
/**
*
* @param head1 ListNode类
* @param head2 ListNode类
* @return ListNode类
*/
function addInList( head1 , head2 ) {
let { len: len1 = 0, pre: node1 = {}} = reverse(head1);
let { len: len2 = 0, pre: node2 = {}} = reverse(head2);
let obj1 = null, obj2 = null, len = 0, t = 0, f = 0, k = 0, v1 = 0, v2 = 0 , pre = null, temp = null;
if(len1 > len2){
len = len1;
obj1 = node1;
obj2 = node2;
}else{
len = len2;
obj1 = node2;
obj2 = node1;
}
while(len > 0){
if(node1){
v1 = node1.val;
node1 = node1.next;
}else{
v1 = 0;
}
if(node2){
v2 = node2.val;
node2 = node2.next;
} else{
v2 = 0;
}
if(v1 === null || v1 === undefined){
v1 = 0;
}
if(v2 === null || v2 === undefined){
v2 = 0;
}
t = v1 + v2 + f;
k = t;
if(t >= 10){
t = t % 10;
f = 1;
}else{
f = 0;
}
obj1.val = t;
temp = obj1.next;
obj1.next = pre;
pre = obj1;
obj1 = temp;
len -= 1;
}
if(k >= 10){
let B = new ListNode(1);
B.next = pre;
pre = B;
}
return pre;
}
module.exports = {
addInList : addInList
};
效果还是蛮好的
来自牛客编程题 牛客编程题