首先需要了解链表的概念
无论是插入,删除,还是翻转等等操作,先把 next 指针用临时变量保存起来,这可以解决 90% 重组链表中指向出错的问题,
类型守卫 emptyNode 是创建的一个空的节点,并将它连接到 head 节点之前,无论链表进行任何操作, emptyNode 都指向最后的头节点,是一个很实用的小方法,如果不知道什么时候用,什么时候不用,那就先都用起来吧;
其实在大部分时候,emptyNode 都是能用上,即便只是遍历查找值,用上作为第 0 个值,当要找第 k 个值的时候,也不需要再判空处理啊
如果懒或者经常忘记看题目的给定条件,头节点判空都做起来,对于一些翻转题,还得将 head.next 也判断起来;
到熟练之后,其实可以不做,但是用上最多就浪费一段代码,也还好
遇事不决的时候,还是要画图,一步一步的连起来,总能够捋清楚的,画图是链表的关键所在
链表是一个特定的数据结构,在 JS 中可以表现为一个拥有 val 和 next 属性的对象,所以遇到形如交换两个链表节点的时候,千万不能交换两个链表的 val 值,虽然 LC 有一些题是可以过,但是实际上是不合理的,而且一旦出现这种思想,对于一些经典题 160. 相交链表 就会理解不了;
记住,链表是一个数据结构,不是一个值,可以类比成一个对象,交换链表比如不是简单交换值;
这里选的都是按照 LC 火热排序,中等难度的题,感觉纯链表学习做特别难没太大必要,毕竟我只是一个菜鸟,大佬们可以自由选择,一起 ,进大厂;
分析
var reverseList = function (head) {
let prev = null;
while (head) {
const next = head.next;
head.next = prev;
prev = head;
head = next;
}
return prev;
};
分析
/** * @分析 * 1. 这里的返回值是按照十进制计算后的 `链表` */
var addTwoNumbers = function (l1, l2) {
const emptyNode = new ListNode();
let current = emptyNode;
let isUpper = 0; // 是否满10,为后面的位+1
while (l1 && l2) {
let sum = l1.val + l2.val + isUpper;
if (sum >= 10) {
isUpper = 1;
sum = sum % 10;
} else {
isUpper = 0;
}
current.next = new ListNode(sum);
current = current.next;
l1 = l1.next;
l2 = l2.next;
}
let l3 = l1 || l2; //剩余的那个链表
while (l3) {
let sum = l3.val + isUpper;
if (sum >= 10) {
isUpper = 1;
sum = sum % 10;
} else {
isUpper = 0;
}
current.next = new ListNode(sum);
current = current.next;
l3 = l3.next;
}
if (isUpper) {
// 遍历完了,如果还有进位
current.next = new ListNode(isUpper);
current = current.next;
}
return emptyNode.next;
};
参考视频:传送门
分析
var addTwoNumbers = function (l1, l2) {
const emptyNode = (current = new ListNode());
// 翻转量个链表,让他们头节点对齐
let temp1 = reverseList(l1);
let temp2 = reverseList(l2);
let isUpper = 0; // 是否满10,为后面的位+1
while (temp1 && temp2) {
let sum = temp1.val + temp2.val + isUpper;
if (sum >= 10) {
isUpper = 1;
sum = sum % 10;
} else {
isUpper = 0;
}
current.next = new ListNode(sum);
current = current.next;
temp1 = temp1.next;
temp2 = temp2.next;
}
let l3 = temp1 || temp2; //剩余的那个链表
while (l3) {
let sum = l3.val + isUpper;
if (sum >= 10) {
isUpper = 1;
sum = sum % 10;
} else {
isUpper = 0;
}
current.next = new ListNode(sum);
current = current.next;
l3 = l3.next;
}
if (isUpper) {
// 遍历完了,如果还有进位
current.next = new ListNode(isUpper);
current = current.next;
}
return reverseList(emptyNode.next);
};
// 反转链表
var reverseList = function (head) {
let prev = null;
while (head) {
const next = head.next;
head.next = prev;
prev = head;
head = next;
}
return prev;
};
分析:
var rotateRight = function (head, k) {
// 先求链表的长度
let len = 0,
tempNode = head;
while (tempNode) {
len++;
tempNode = tempNode.next;
}
// 需要位移 size 到头节点
let size = len - (k % len);
let prev = new ListNode();
prev.next = head;
let cur = head;
while (size