目录
学习计划链接
题目解析
1. 剑指 Offer II 021. 删除链表的倒数第 n 个结点
1) 问题描述
2) 思路分析
快慢指针
- 定义快慢指针,让快指针先走n-1步;
- 若quick指针走了n-1步后指向链表尾结点,则说明倒数第n个为头节点;
- 否则, quick与slow同步走,当quick指向尾结点时,slow指向的即为倒数第n个节点。
3) leetcode链接
剑指 Offer II 021. 删除链表的倒数第 n 个结点
4) 代码实现
/**
* 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) {
//快慢指针
ListNode *quick=head;
ListNode *slow=head;
ListNode *prev=nullptr;
//1.快指针先走n-1步.
int i=0;
while(quick->next&& i<n-1)
{
quick=quick->next;
i++;
}
//若quick指针走了n-1步后指向链表尾结点,则说明倒数第n个为头节点;
if(quick->next==nullptr)
{
ListNode *to_delete=head;
head=head->next;
delete to_delete;
return head;
}
//quick与slow同步走,当quick指向尾结点时,slow指向的即为倒数第n个节点。
while(quick->next!=nullptr)
{
quick=quick->next;
prev=slow; //记录倒数第k个节点的前一个节点,用于删除。
slow=slow->next;
}
//
ListNode *to_delete=slow;
prev->next=slow->next;
delete to_delete;
return head;
}
};
2. 剑指 Offer II 022. 链表中环的入口节点
1) 问题描述
2) 思路分析
- 快慢指针,找相遇点(快指针走两步,慢指针走一步,直到快慢指针相遇)
- 双指针同步走,找入口(一个指针从头开始,另一个指针从相遇点开始,直到两个指针相遇)
3) leetcode链接
4) 代码实现
/**
* 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) {
if (head == nullptr || head->next == nullptr) {
return nullptr;
}
//1.快慢指针,找相遇点
ListNode *slow=head->next;
ListNode *quick=slow->next;
while((quick && quick->next && quick!=slow))
{
quick=quick->next->next;
slow=slow->next;
}
if(quick==nullptr||quick->next==nullptr)
{
return nullptr;
}
ListNode *meet = quick;
//2.双指针同步走,找入口
quick =meet;
slow=head;
while(quick!=slow)
{
quick=quick->next;
slow=slow->next;
}
return quick;
}
};
3. 剑指 Offer II 023. 两个链表的第一个重合节点
1) 问题描述
2) 思路分析
- 遍历两个链表求两个链表的长度分别为lA,和lB;
- 较长的链表先走|lA-lB|步
- 双方同步走,直到相遇
3) leetcode链接
4) 代码实现
/**
* 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) {
//1.遍历两个链表求两个链表的长度分别为lA,和lB;
int lA=0;
int lB=0;
ListNode *cur=headA;
while(cur)
{
lA++;
cur=cur->next;
}
cur=headB;
while(cur)
{
lB++;
cur=cur->next;
}
ListNode* quick=nullptr;
ListNode* slow=nullptr;
//2.较长的链表先走|lA-lB|步
if(lA>lB)
{
int k=lA-lB;
quick=headA;
slow=headB;
while(k--)
{
quick=quick->next;
}
}
else
{
int k=lB-lA;
quick=headB;
slow=headA;
while(k--)
{
quick=quick->next;
}
}
//3.双方同步走,直到相遇
while(quick && quick!=slow)
{
quick=quick->next;
slow=slow->next;
}
return quick;
}
};