17. 环形链表 II
var detectCycle = function(head) {
let fast = head, slow = head;
do{
//检查是否有环 + 寻找相遇点 encounter point
if(!fast || !fast.next) return null;
fast = fast.next.next
slow = slow.next
}while(fast != slow)
fast = head;
//寻找入口 entrance
//为什么这能寻找入口,请看下图
while(fast != slow){
fast = fast.next
slow = slow.next
}
return fast;
};
58. 环形链表
var hasCycle = function(head) {
let fast = head;
let slow = head;
while (fast &&fast.next&& slow){
fast = fast.next.next
slow = slow.next
if(fast === slow){
return true;
}
}
return false
};
25. 删除链表的倒数第 N 个结点
Fast 先走k次,再一起走的的时候fast走没了 就是slow要删除节点的时候;返回值为head
var removeNthFromEnd = function(head, n) {
let fast = head;
let slow = head;
for(let i=0;i<n;i++){
fast = fast.next
}
// 如果fast为null 说明删除第一个 直接取第二个即可
if(fast == null)return head.next;
while (fast&&fast.next!=null){
fast = fast.next
slow = slow.next
}
// .next时候才能跳过 要不然相当改的是变量值
slow.next = slow.next.next
return head;
};
88.两两交换链表中的节点
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
function swapPairs(head) {
// 创建一个哨兵节点,它的next指针指向链表的头节点
let dummy = new ListNode(0);
dummy.next = head;
// 当前节点指针初始化为哨兵节点
let current = dummy;
while (current.next !== null && current.next.next !== null) {
// 初始化两个待交换节点
let firstNode = current.next;
let secondNode = current.next.next;
// 交换操作
firstNode.next = secondNode.next;
secondNode.next = firstNode;
current.next = secondNode;
// 移动当前节点指针至下一对待交换节点的前驱节点
current = firstNode;
}
// 返回哨兵节点的下一个节点,即交换后的头节点
return dummy.next;
}
19. 反转链表
var reverseList = function(head) {
let pre = null // 反转链表
let current = head
while (current){
// 临时存当前节点的下一个
const tempCurrent = current.next
// 当前的 下一个指向上一个
current.next = pre
// 反转拼接
pre = current
// 当前继续循环
current = tempCurrent
}
return pre
};
30. K 个一组翻转链表
给你链表的头节点
head
,每k
**个节点一组进行翻转,请你返回修改后的链表。
var reverseKGroup = function(head, k) {
let currentNode = head;
let count = 0;
// 计数检查是否有足够的节点进行下一次翻转
while (currentNode != null && count != k) {
currentNode = currentNode.next;
count++;
}
// 如果有足够的节点进行翻转
if (count == k) {
// 翻转这 k 个节点
currentNode = reverseKGroup(currentNode, k); // 翻转剩余部分,并将结果连接到当前部分
while (count-- > 0) { // 翻转当前 k 个节点
let temp = head.next; // 临时保存下一个节点
head.next = currentNode; // 将当前节点的 next 指向翻转的剩余部分
currentNode = head; // 将 currentNode 移动到当前节点
head = temp; // 移动 head 到下一个节点
}
head = currentNode;
}
return head;
};
24. 合并两个有序链表
var mergeTwoLists = function(list1, list2) {
let temp = new ListNode(0);
// 存着这个链表节点 一直做赋值用
let result = temp
while (list1!==null&&list2!=null){
if(list1.val<=list2.val){
// 赋值
result.next = list1
// 跳转
list1 = list1.next
}else{
result.next = list2
list2 = list2.next
}
// 跳转
result = result.next
}
// 没遍历完的直接拼接
result.next = list1||list2
return temp.next;
};
61. 相交链表
var getIntersectionNode = function(headA, headB) {
let ap = headA,
bp = headB;
while (ap !== bp) {
if (ap === null) {
ap = headB;
} else {
ap = ap.next;
}
if (bp === null) {
bp = headA;
} else {
bp = bp.next;
}
}
return ap;
};
77.两个链表的第一个公共节点
var getIntersectionNode = function(headA, headB) {
if(!headA||!headB) return null;
// 走完自己的 在另一方一步一步走 相当于第二次循环必会相遇
var a=headA,b=headB;
while(a!=b){
a=a?a.next:headB;
b=b?b.next:headA;
}
return a;
};
62. 合并 K 个升序链表
var mergeKLists = function (lists) {
const list = [];
for (let i = 0; i < lists.length; i++) {
let node = lists[i];
while (node) {
list.push(node.val);
node = node.next;
}
}
list.sort((a, b) => a - b);
const res = new ListNode();
let now = res;
// console.log(list)
for (let i = 0; i < list.length; i++) {
now.next = new ListNode(list[i]);
now = now.next;
}
return res.next;
};
// 分治
function mergeTwoLists(l1, l2) {
if (!l1) return l2;
if (!l2) return l1;
if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
function mergeKLists(lists) {
if (lists.length === 0) return null;
if (lists.length === 1) return lists[0];
const mid = Math.floor(lists.length / 2);
const l1 = mergeKLists(lists.slice(0, mid));
const l2 = mergeKLists(lists.slice(mid));
return mergeTwoLists(l1, l2);
}
78.复杂链表的复制
var copyRandomList = function(head) {
if (!head) {
return null;
}
const map = new Map();
let node = head; // 当前节点
const newHead = new Node(node.val);
let newNode = newHead; // 当前节点的copy
map.set(node, newNode);
while (node.next) {
newNode.next = new Node(node.next.val);
node = node.next;
newNode = newNode.next;
map.set(node, newNode);
}
newNode = newHead;
node = head;
while (newNode) {
newNode.random = map.get(node.random);
newNode = newNode.next;
node = node.next;
}
return newHead;
};