一、02两数相加
问题描述
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]
解题思路
这个题目的解题思路还是很简单的,首先需要新建一个链表存储结果,其余按照普通的加法做计算就行,在这里设置了一个进位数来存储进位的结果,需要注意的是在链表全部遍历结束后,仍需要对进位数进行一个判断,当其大于0时,需增加一个节点记录进位。具体代码如下:
var addTwoNumbers =function(l1,l2){
let head=null,tail=null; //记录新链表的头节点和尾节点
let count=0; //记录进位
while(l1||l2){ //这里的判断条件不是&&,因为当一个链表遍历结束后,可以将其值视为0,再与另一个链表的值相加,这样可以当作一类讨论,不做其他处理,代码更简洁
const n1=l1?l1.val:0;
const n2=l2?l2.val:0;
const sum=n1+n2+count;
if(!head){
head=tail=new ListNode(sum%10);
}else{//尾插法新建列表
tail.next=new ListNode(sum%10);
tail=tail.next;
}
count=Math.floor(sum/10);
if(l1){
l1=l1.next;
}
if(l2){
l2=l2.next;
}
}
//链表全部遍历结束后检查count有无进位
if(count>0){
tail.next=new ListNode(carry);
}
return head;
}
二、19 删除链表的倒数第N个节点
题目描述
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
解题思路
这个题的解题思路也是比较常规的一个了,看到题目就知道是先找到倒数第n个节点,然后就是删除就好。这里有两个值得注意的点,第一个需要设置虚假头节点防止真正的头节点被删除,无法返回结果;第二个是在删除节点时往往需要找到其前置节点,才能删除当前节点,所以在找倒数第n个节点时,我们可以将找第n个节点转化为找第n+1个节点,这样就不需要专门记住其前置节点 了,代码更加简洁。具体代码如下:
var removeNthFromEnd = function(head, n) {
const dummyhead=new ListNode(0);
dummyhead.next=head;
let pre=fast=dummyhead;
//找到倒数n+1个节点
while(n-->0){
fast=fast.next;
}
//fast走到最后,此时pre时倒数第n个元素的前一个元素
while(fast&&fast.next){
pre=pre.next;
fast=fast.next;
}
pre.next=pre.next.next;
return dummyhead.next;
};
三、21 合并两个有序列表
题目描述
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
解题思路
简单题,解题思路也很简单,就是不断比较然后结合成新的链表就好了。
var mergeTwoLists = function(list1, list2) {
if(list1==null&&list2==null) return null;
let dummyhead=new ListNode(0);
let cur=dummyhead;
while(list1&&list2){
if(list1.val<=list2.val){
cur.next=list1;
list1=list1.next;
}else{
cur.next=list2;
list2=list2.next;
}
cur=cur.next;
}
while(list1){
cur.next=list1;
list1=list1.next;
cur=cur.next;
}
while(list2){
cur.next=list2;
list2=list2.next;
cur=cur.next;
}
return dummyhead.next;
};
三、技巧总结
- 对于链表问题,在返回结果为头节点时,通常需要先初始化一个预先指针pre或者说假性头节点dummyhead,该指针的下一个节点指向真正的头节点head。这是为了在链表构造或者移动过程中,防止头指针丢失,从而无法返回结果。
- 快慢指针找节点,这个就是模板了感觉,找第n个,倒数第n个,以及中间节点,都是相同的套路,注意快慢指针之间的间隔就好了。