两个链表的公共子结点
-
集合
将一个链表的结点全部存入集合,遍历第二个链表
-
栈
将两个链表的结点分别存入两个栈,栈顶元素相等则同时出栈,公共结点为最后出栈的结点
-
😊😊遍历 AB 和 BA,空间复杂度O(1)
var findFirstCommonNode(head1, head2) {
if(!head1 || !head2) return null;
let p1 = head1;
let p2 = head2;
while(p1 != p2) {
p1 = p1.next;
p2 = p2.next;
// 避免不存在公共结点陷入循环!!!
if(p1 != p2) {
// 访问结束一个链表就访问另一个链表
if(!p1) p1 = head2;
if(!p2) p2 = head1;
}
}
return p1;
}
链表是否为回文序列 LeetCode234
-
栈
将链表结点全部入栈,一边出栈一边遍历链表对比
😊😊将链表结点全部入栈并记录长度,一边出栈一边遍历链表对比,达到半长度后停止出栈
var isPalindrome = function(head) { let p = head; let stack = new Array(); let length = 0; while(p) { stack.push(p.val); ++length; p = p.next; } p = head; for(let i = 0; i < length / 2; ++i) { if(stack.pop() != p.val) { return false; } p = p.next; } return true; };
合并有序链表
-
合并两个升序链表
新建一个链表,分别遍历两个链表取最小值作为新结点
-
合并多个链表
((((1 + 1)+ 1) + 1) + 1…
双指针
中间结点 LeetCode876
-
快慢指针,slow 一次一步,fast 一次两步,注意偶数长度返回哪个值
var middleNode = function(head) { let slow = head; let fast = head; while(fast?.next) { slow = slow.next; fast = fast.next.next; } return slow; };
倒数k个元素
- 快慢指针,fast先走到第 k + 1 个结点
旋转链表 LeetCode61
- 快慢指针,相当于将倒数 k % length 个结点移到开头,fast先走到 k % length + 1 个结点
var rotateRight = function(head, k) {
if(!head) return head;
let slow = head;
let fast = head;
let length = 0;
let temp = head;
let pre1 = head;
let post1 = head;
let pre2, post2;
while(temp) {
temp = temp.next;
++length;
}
k %= length;
if(k == 0) return head;
let i = 0;
while(i < k - 1) {
fast = fast.next;
++i;
}
while(fast?.next) {
post1 = slow;
slow = slow.next;
fast = fast.next;
}
pre2 = slow;
post2 = fast;
post1.next = null;
post2.next = pre1;
return pre2;
};
删除结点
删除特定结点 LeetCode203
- 建立dummyHead
var removeElements = function(head, val) {
let dummyHead = new ListNode(-1, head);
let p = dummyHead;
while(p?.next) {
if(p.next.val === val) {
p.next = p.next.next;
continue;
}
p = p.next;
}
return dummyHead.next;
};
删除倒数第n个结点 LeetCode19
- 快慢指针
var removeNthFromEnd = function(head, n) {
let dummyHead = new ListNode(-1, head);
let fast = dummyHead;
let slow = dummyHead;
let count = 0;
while(count < n) {
fast = fast.next;
++count;
}
while(fast.next) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummyHead.next;
};
删除重复元素
- 保留一个重复元素 LeetCode83
var deleteDuplicates = function(head) {
let p = head;
while(p?.next) {
if(p.val === p.next.val) {
p.next = p.next.next
continue;
}
p = p.next;
}
return head;
};
-
不保留重复元素 LeetCode82
虚拟头节点
var deleteDuplicates = function(head) {
let dummyHead = new ListNode(-1, head);
let p = dummyHead;
while(p?.next?.next) {
if(p.next.val == p.next.next.val) {
let p2 = p.next.next;
while(p2?.next) {
if(p2.val != p2.next.val) break;
p2 = p2.next;
}
p.next = p2.next;
continue;
}
p = p.next;
}
return dummyHead.next;
};