如果有其他更好的方法,欢迎在评论区留言~
题目描述
假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
给定两个这种链表,请生成代表两个整数相加值的结果链表。
数据范围:0≤n,m≤1000000,链表任意值 0≤val≤9
要求:空间复杂度 O(n),时间复杂度 O(n)
例如:链表 1 为 9->3->7,链表 2 为 6->3,最后生成新的结果链表为 1->0->0->0。
知识点
链表、模拟
示例
输入:
[9,3,7],[6,3]
返回值:
{1,0,0,0}
输入:
[0],[6,3]
返回值:
{6,3}
1≤n,m≤10^6
0≤ai,bi≤9
解题过程
方法一:反转链表
具体做法:
- step 1:任意一个链表为空,返回另一个链表就行了,因为链表为空相当于0,0加任何数为0,包括另一个加数为0的情况。
- step 2:相继反转两个待相加的链表。
- step 3:设置返回链表的链表头,设置进位carry=0。
- step 4:从头开始遍历两个链表,直到两个链表节点都为空且carry也不为1. 每次取出不为空的链表节点值,为空就设置为0,将两个数字与carry相加,然后查看是否进位,将进位后的结果(对10取模)加入新的链表节点,连接在返回链表后面,并继续往后遍历。
- step 5:返回前将结果链表再反转回来。
/*
* function ListNode(x){
* this.val = x;
* this.next = null;
* }
*/
/**
*
* @param head1 ListNode类
* @param head2 ListNode类
* @return ListNode类
*/
function addInList(head1, head2) {
// write code here
if(head1==null){
return head2;
}
if(head2==null){
return head1;
}
head1=reverseList(head1);
head2=reverseList(head2);
var head=new ListNode(-1),nHead=head; //创建新的链表头结点
var carry=0; //记录进位的数值
while(head1!=null || head2!=null){
var val=carry; //累加此时的数值(head1的值+head2的值+上一位的进位=当前总数值)
if(head1!=null){ // 当节点不为空的时候,则需要加上当前节点的值
val=val+head1.val;
head1=head1.next;
}
if(head2!=null){ // 当节点不为空的时候,则需要加上当前节点的值
val=val+head2.val;
head2=head2.next;
}
carry=Math.floor(val/10); //求出进位
nHead.next=new ListNode(val%10); //进位后剩下的数值即为当前节点的值
nHead=nHead.next;
}
if(carry>0){ // 最后当两条链表都加完的时候,进位不为0的时候,则需要再加上这个进位
nHead.next=new ListNode(carry);
}
return reverseList(head.next);
}
function reverseList(pHead){
if(pHead==null || pHead.next==null){
return pHead;
}
var pre=null,cur=pHead; //反转链表
while(cur){
var temp=cur.next;
cur.next=pre;
pre=cur;
cur=temp;
}
return pre;
}
module.exports = {
addInList: addInList,
};
/*
* function ListNode(x){
* this.val = x;
* this.next = null;
* }
*/
/**
*
* @param head1 ListNode类
* @param head2 ListNode类
* @return ListNode类
*/
function addInList(head1, head2) {
// write code here
if(head1==null){
return head2;
}
if(head2==null){
return head1;
}
head1=reverseList(head1);
head2=reverseList(head2);
var head=new ListNode(-1),nHead=head; //创建新的链表头结点
var carry=0; //记录进位的数值
while(head1!=null || head2!=null || carry!=0){
var val1=head1==null ? 0 : head1.val;
var val2=head2==null ? 0 : head2.val;
var temp=val1+val2+carry;
carry=Math.floor(temp/10);
temp%=10;
nHead.next=new ListNode(temp);
nHead=nHead.next;
if(head1!=null){
head1=head1.next;
}
if(head2!=null){
head2=head2.next;
}
}
return reverseList(head.next);
}
function reverseList(pHead){
if(pHead==null || pHead.next==null){
return pHead;
}
var pre=null,cur=pHead;
while(cur){
var temp=cur.next;
cur.next=pre;
pre=cur;
cur=temp;
}
return pre;
}
module.exports = {
addInList: addInList,
};
复杂度分析
- 时间复杂度:O(max(m,n)),其中m与n分别为两个链表的长度,翻转链表三次,复杂度分别是O(n)、O(m)、O(max(m,n)),相加过程也是遍历较长的链表
- 空间复杂度:O(1),常数级指针,没有额外辅助空间