LeetCode 24
视频讲解链接: 帮你把链表细节学清楚! | LeetCode:24. 两两交换链表中的节点
思路:
- 结合虚拟头结点, 不然每次针对头结点(没有前一个指针指向头结点),还要单独处理
- 节点改变的步骤 / 建议结合画图
- 节点改变步骤举例[2 1 3 4]
- 创建一个虚拟节点 0
- 第一步: 0.next 指向 2
- 第二步: 2.next 指向 1
- 第三步: 1.next 指向 3
代码:
var swapPairs = function(head) {
if(!head) return head
let dummyHead = new ListNode(0, head)
let cur = dummyHead
while(cur.next && cur.next.next){
let temp1 = cur.next
let temp2 = cur.next.next
let temp3 = cur.next.next.next
cur.next = temp2
temp2.next = temp1
temp1.next = temp3
cur = cur.next.next
}
return dummyHead.next
};
LeetCode 19
视频讲解链接: 链表遍历学清楚! | LeetCode:19.删除链表倒数第N个节点
思路:
- 使用双遍历, 第一次获取整体链表长度, 求出 n 前一个节点的位置
- 第二次找到 n 前一个节点 prev 且 prev.next = prev.next.next
代码:
var removeNthFromEnd = function(head, n) {
let length = 1
let loop = head
while(loop.next){
loop = loop.next
length++
}
let target = length - n
if(target === 0){
return head = head.next
}
let preNode = getNode(head, target)
console.log(head, target)
preNode.next = preNode.next.next
return head
};
function getNode(head, index){
let dummyHead = new ListNode(0, head)
let cur = dummyHead
while(index-- > 0){
cur = cur.next
}
return cur
}
思路(双指针):
- 设置一个快指针 一个慢指针
- 快指针先走 n + 1 步, 然后 快慢指针同时走, 直到快指针为null
- 这样慢指针就停在了n前一个节点 prev
- 然后 prev.next = prev.next.next
代码
var removeNthFromEnd = function(head, n) {
let dummyHead = new ListNode(0, head)
let fast = dummyHead, slow = dummyHead
while(n--) fast = fast.next
while(fast.next){
fast = fast.next
slow = slow.next
}
slow.next = slow.next.next
return dummyHead.next
};
面试题 02.07. 链表相交
思路:
- 先获取两个链表的长度
- 让两个链表的尾部对其
- 然后同时进行向后遍历并进行比较
代码:
var getIntersectionNode = function(headA, headB) {
let curA = headA, curB = headB;
let aLen = 0, bLen = 0;
while(curA) {
curA = curA.next;
aLen++;
}
while(curB) {
curB = curB.next;
bLen++;
}
curA = headA; // 重置curA指针到链表A头部
curB = headB; // 重置curB指针到链表B头部
if(aLen < bLen) {
// 交换curA和curB,这样确保curA始终指向最长的链表
[curA, curB] = [curB, curA];
[aLen, bLen] = [bLen, aLen];
}
let diff = aLen - bLen;
while(diff-- > 0) {
curA = curA.next;
}
while(curA && curA !== curB) {
curA = curA.next;
curB = curB.next;
}
return curA;
};
LeetCode 142
视频讲解链接: 把环形链表讲清楚! 如何判断环形链表?如何找到环形链表的入口? LeetCode:142.环形链表II
代码
var detectCycle = function (head) {
if (!head || !head.next) return null;
let slow = head,
fast = head;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
if (slow === fast) {
slow = head;
while (slow !== fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
return null;
};