https://leetcode.cn/problems/remove-nth-node-from-end-of-list/
快慢指针的应用
/**
* 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) {
if(head == nullptr || head->next == nullptr)
{
return nullptr;
}
ListNode* fast = head;
ListNode* slow = head;
ListNode* prev = nullptr;
//fast指针先移动N步,slow依然指向head
for(int i = 0; i < n; i++)
{
fast = fast->next;
}
//然后fast和slow同时移动,直到fast指向链表最后一个节点的next,也就是空,此时slow就指向了倒数第N个节点
while(fast)
{
fast = fast->next;
prev = slow;
slow = slow->next;
}
if(prev)
{
prev->next = slow->next;
delete(slow);
}
else // 如果prev为空,则删除的是头结点
{
prev = head;
head = head->next;
delete(prev);
}
return head;
}
};
https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/description/
/**
* 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) {
int cntA = 0, cntB = 0;
ListNode* curA = headA;
ListNode* curB = headB;
//遍历得到AB的长度
while(curA)
{
cntA++;
curA = curA->next;
}
while(curB)
{
cntB++;
curB = curB->next;
}
//计算长度差,让长链表先走
int skip = abs(cntA - cntB);
ListNode* longerList = headA;
ListNode* shorterList = headB;
if(cntA < cntB)
{
swap(longerList, shorterList);
}
curA = longerList;
curB = shorterList;
while(skip--)
{
curA = curA->next;
}
//两个指针一起走
while(curA != curB)
{
curA = curA->next;
curB = curB->next;
}
return curA;
}
};
https://leetcode.cn/problems/linked-list-cycle-ii/description/
判断链表是否有环
找到这个环的入口
(x + y) * 2 = x + y + n (y + z)
x + y = n (y + z)
x = n (y + z) - y
x = z
/**
* 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* fast = head;
ListNode* slow = head;
while(fast && fast->next) //如果没有环,fast或者fast->next就会为空
{
fast = fast->next->next; //快指针一次走两步
slow = slow->next; //慢指针一次走一步
//若有环,则fast和slow会在环内相遇
if(fast == slow)
{
//两个指针从相遇节点和头节点同时向后走,最终的相遇点就是环的入口
ListNode* index1 = head;
ListNode* index2 = fast;
while(index1 != index2)
{
index1 = index1->next;
index2 = index2->next;
}
return index2;
}
}
return nullptr;
}
};
https://leetcode.cn/problems/middle-of-the-linked-list/description/
/**
* 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* middleNode(ListNode* head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
};
https://leetcode.cn/problems/aMhZSa/description/
判断一个链表是否为回文结构:
/**
* 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* middleNode(ListNode* head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
ListNode* reverseList(ListNode* head)
{
ListNode* cur = head;
ListNode* reverseHead = nullptr;
while(cur)
{
ListNode* next = cur->next;
cur->next = reverseHead;
reverseHead = cur;
cur = next;
}
return reverseHead;
}
bool isPalindrome(ListNode* head) {
ListNode* mid = middleNode(head);
mid = reverseList(mid);
ListNode* start = head;
while(mid)
{
if(start->val != mid->val)
{
return false;
}
start = start->next;
mid = mid->next;
}
return true;
}
};