24. 两两交换链表中的节点
递归官方题解
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return head;
}
ListNode* newHead = head->next;
head->next = swapPairs(newHead->next);
newHead->next = head;
return newHead;
}
};
19.删除链表的倒数第N个节点
19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)
双指针法:
栈:官方解法
面试题 02.07. 链表相交
面试题 02.07. 链表相交 - 力扣(LeetCode)
方法一官方解法:
哈希集合存储链表节点A,遍历链表B,对遍历到的每个节点,判断该节点是否在哈希集合中,B 中遍历到的第一个在哈希集合中的节点就是两个链表相交的节点
方法二官方解法:双指针
其中至少有一个链表为空,则两个链表一定不相交
都不为空时,创建两个指针 pA和pB,初始时分别指向两个链表的头节点 headA和headB,将两个指针依次遍历两个链表的每个节点。pA为空,则将指针pA移到链表headB的头节点;如果指针 pB为空,则将指针pB移到链表 headA 的头节点,当指针pA和pB指向同一个节点或者都为空时,返回它们指向的节点或者null。
相交:headAheadB链表相交部分有c个结点,A不相交部分有a个结点,B不相交部分有b个结点,
1.若a=b,两个指针会同时到达两个链表相交结点
2.若a!=b,指针pA移动到链表B的头结点继续移动,指针pB移到链表A的头结点再继续移动,
指针pA移动了a+b+c次时,指针pB移动了b+c+a次,同时到达两个链表相交的结点
不相交:headAheadB的长度分别为m、n。
m=n时,两个指针同时到两个链表尾结点,同时成为null,返回null;
m!=n时,pA移动m+n次遍历完AB链表,pB移动n+m次遍历完BA链表,同时为null,返回null。
方法三代码随想录: 代码随想录 (programmercarl.com)
求出两个链表的长度,尾部对齐,A移动到B头部相同位置,同时向后移动,相等时找到交点,不相交循环退出返回空指针。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* curA = headA;
ListNode* curB = headB;
int lenA = 0, lenB = 0;
while (curA != NULL) { // 求链表A的长度
lenA++;
curA = curA->next;
}
while (curB != NULL) { // 求链表B的长度
lenB++;
curB = curB->next;
}
curA = headA;
curB = headB;
// 让curA为最长链表的头,lenA为其长度
if (lenB > lenA) {
swap (lenA, lenB);
swap (curA, curB);
}
// 求长度差
int gap = lenA - lenB;
// 让curA和curB在同一起点上(末尾位置对齐)
while (gap--) {
curA = curA->next;
}
// 遍历curA 和 curB,遇到相同则直接返回
while (curA != NULL) {
if (curA == curB) {
return curA;
}
curA = curA->next;
curB = curB->next;
}
return NULL;
}
};
142.环形链表II
方法一代码随想录:代码随想录 (programmercarl.com)
快慢指针:fast指针两步,slow指针一步,对slow来说,fast每次多一步追赶slow,有环则必然相遇,相遇点fast是slow路径的二倍,减去重合路径部分,fast比slow多走了一个(n个)环总长,环总长(n个)与slow到达相遇点的路径长相等,环总长(n个)减去slow在环内走过的路径长与slow减去slow在环内走过的路径长相等,
以相遇点为起始点,指针1走过“环总长(n个)减去slow在环内走过的路径长”(slow第一次到达入口点时,fast在环内走过的长度,也是fast比slow多走的长度)
以头结点为起始点,指针2走过“slow减去slow在环内走过的路径长”,
此时两指针相遇,共同处于环入口位置
方法二:
遍历链表中的每个节点,并记录,一旦遇到了此前遍历过的节点,就可以判定链表中存在环。
链表通常需要设置虚拟头结点便于操作,常用双指针法,
还可以用递归、栈、快慢指针等方法解决问题