返回
剖析链表:JavaScript实现LeetCode中的经典算法挑战
前端
2023-12-27 07:10:50
链表的结构与操作
链表是一种线性的数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表的优点在于其插入和删除操作的效率很高,但随机访问某个节点的效率较低。
链表划分
链表划分的目的是将链表中的节点根据某个值进行划分,使得所有小于该值的节点都在大于或等于该值的节点之前。
JavaScript实现:
function partition(head, x) {
// 创建两个虚拟头节点,分别用于存放小于x和大于或等于x的节点
let lessHead = new ListNode(0);
let lessCur = lessHead;
let greaterHead = new ListNode(0);
let greaterCur = greaterHead;
// 遍历原链表,将节点分别添加到lessHead或greaterHead之后
while (head) {
if (head.val < x) {
lessCur.next = head;
lessCur = lessCur.next;
} else {
greaterCur.next = head;
greaterCur = greaterCur.next;
}
head = head.next;
}
// 将两个链表连接起来
lessCur.next = greaterHead.next;
// 返回lessHead作为新链表的头节点
return lessHead.next;
}
环形链表
环形链表是指链表中存在一个环,即某个节点指向了前面的某个节点,导致链表形成一个闭环。
JavaScript实现:
function hasCycle(head) {
// 创建两个指针,slow和fast,分别以不同的速度遍历链表
let slow = head;
let fast = head;
// 如果fast和fast.next都为null,则链表中没有环
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
// 如果slow和fast相遇,则链表中存在环
if (slow === fast) {
return true;
}
}
// 如果fast和fast.next都为null,则链表中没有环
return false;
}
相交链表
相交链表是指两个链表在某个节点之后合并,形成一个公共的尾部。
JavaScript实现:
function getIntersectionNode(headA, headB) {
// 计算两个链表的长度
let lenA = 0;
let lenB = 0;
let curA = headA;
let curB = headB;
while (curA) {
lenA++;
curA = curA.next;
}
while (curB) {
lenB++;
curB = curB.next;
}
// 让较长的链表先走lenA-lenB步,这样两个链表的长度相同
if (lenA > lenB) {
for (let i = 0; i < lenA - lenB; i++) {
headA = headA.next;
}
} else if (lenB > lenA) {
for (let i = 0; i < lenB - lenA; i++) {
headB = headB.next;
}
}
// 同时遍历两个链表,直到找到相交的节点
while (headA && headB) {
if (headA === headB) {
return headA;
}
headA = headA.next;
headB = headB.next;
}
// 如果没有找到相交的节点,返回null
return null;
}
结语
通过本文对链表的深入探讨,读者对链表的结构、操作和经典算法有了更深入的了解。JavaScript作为一门灵活且强大的语言,为链表的实现提供了丰富的支持。希望本文能激发读者对数据结构与算法的兴趣,并为他们未来的学习和实践打下坚实的基础。