24. 两两交换链表中的节点
leetcode链接
代码随想录链接
一刷状态:通过
思路
保存三个需要交互的节点,根据下方的逻辑交换即可。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyHead = new ListNode(0, head);
ListNode* cur = dummyHead;
while(cur->next!=nullptr && cur->next->next!=nullptr)
{
ListNode* temp1 = cur->next;
ListNode* temp2 = cur->next->next;
ListNode* temp3 = cur->next->next->next;
cur->next = temp2;
cur->next->next = temp1;
cur->next->next->next = temp3;
cur = cur->next->next;
}
return dummyHead->next;
}
};
19.删除链表的倒数第N个节点
leetcode链接
代码随想录链接
一刷状态:通过
思路
使用快慢指针,快指针先出发n+1个节点,因为需要让慢指针遍历到删除节点的前一个节点,所以快指针需要多走一步。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
// 使用快慢指针,快指针先出发n个节点
ListNode* dummyHead = new ListNode(0, head);
ListNode* fastHead = dummyHead;
ListNode* slowHead = dummyHead;
while(n--)
{
fastHead = fastHead->next;
}
fastHead = fastHead->next;
while(fastHead!=nullptr)
{
fastHead = fastHead->next;
slowHead = slowHead->next;
}
slowHead->next = slowHead->next->next;
return dummyHead->next;
}
};
面试题 02.07. 链表相交
leetcode链接
代码随想录链接
一刷状态:通过
思路
用一个土味情话讲,两个最终会走到一起的人,可能会因为前期不同步而无法相遇,所以在重新来过时,可以交换彼此走过的路,最终就能相遇。
话说回来,就是先一起遍历一次A和B链表,然后再交换遍历,即一起遍历一次AB和BA,如果列表相交,就会知道相等的列表节点,然后不相交,也会在结束的时候都等于空指针。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* cur1 = headA;
ListNode* cur2 = headB;
while(cur1!=cur2)
{
if(cur1==nullptr) cur1 = headB;
else cur1 = cur1->next;
if(cur2==nullptr) cur2 = headA;
else cur2 = cur2->next;
}
return cur1;
}
};
142.环形链表II
leetcode链接
代码随想录链接
一刷状态:通过
思路
- 判断是否有环
快慢指针,在环内就会相遇。 - 找到入环节点
找到相遇点,从起点和相遇点一个一个节点遍历,相遇就是入环点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
// 判断是否有环
ListNode* fastNode = head;
ListNode* slowNode = head;
while(fastNode!=nullptr && fastNode->next!=nullptr)
{
fastNode = fastNode->next->next;
slowNode = slowNode->next;
if(fastNode==slowNode) break;
}
if(fastNode==nullptr || fastNode->next==nullptr)
{
return nullptr;
}
// 找到入环节点
ListNode* node1 = head;
ListNode* node2 = fastNode;
while(node1 != node2)
{
node1 = node1->next;
node2 = node2->next;
}
return node1;
}
};
改进版
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fastNode = head;
ListNode* slowNode = head;
while(fastNode != NULL && fastNode->next != NULL)
{
fastNode = fastNode->next->next;
slowNode = slowNode->next;
if(fastNode==slowNode)
{
ListNode* node1 = head;
ListNode* node2 = fastNode;
while(node1!=node2)
{
node1 = node1->next;
node2 = node2->next;
}
return node1;
}
}
return NULL;
}
};