Leetcode24. 两两交换链表中的节点
题目链接:
[24. 两两交换链表中的节点 - 力扣(Leetcode)]
思路:
- 题意为两两交换即两两为一组进行指针操作后循环
- 采用头结点
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode *headNode = new ListNode(0);
headNode->next=head;
ListNode *cur =headNode;
while(cur->next!=nullptr&&cur->next->next!=nullptr)
{
ListNode *node1=cur->next;
ListNode *node3=cur->next->next->next;
cur->next=node1->next;
cur->next->next=node1;
node1->next=node3;
cur=node1;
}
return headNode->next;
}
};
注意的问题:
- 注意每次循环后cur的位置,理清中间需要存储的变量即可
Leetcode19. 删除链表的倒数第 N 个结点
题目链接:
[19. 删除链表的倒数第 N 个结点 - 力扣(Leetcode)]
思路:
- 快慢指针
- 快指针先走n步
- 慢指针再与其一同出发直至快指针走至尽头
- ==注意:==删除结点需找到前一个结点,因此设一个虚拟头结点作为起始快慢指针位置
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *headNode = new ListNode(0);
ListNode *fast =headNode;
ListNode *slow =headNode;
headNode->next=head;
while(n--)
{
fast=fast->next;
}
while(fast->next!=nullptr)
{
fast=fast->next;
slow=slow->next;
}
slow->next=slow->next->next;
return headNode->next;
}
};
Leetcode面试题 02.07. 链表相交
题目链接:
[面试题 02.07. 链表相交 - 力扣(Leetcode)]
思路:
- 与上一题类似使用快慢指针
- 区别在于不知道快指针先走几步以及不知道哪个链表快
- 首先遍历一遍记录两个链表长度
- 快指针即链表长的,慢指针即链表短的
- 同理快指针先走链表长度差,直至快慢指针相遇
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *cur1=headA;
ListNode *cur2=headB;
int a=1,b=1;
while(cur1!=NULL)
{
cur1=cur1->next;
a++;
}
while(cur2!=NULL)
{
cur2=cur2->next;
b++;
}
int sub=0;
cur1=headA;
cur2=headB;
if(a>b)
{
sub=a-b;
while(sub--)
{
cur1=cur1->next;
}
}
else{
sub=b-a;
while(sub--)
{
cur2=cur2->next;
}
}
while(cur1!=NULL&&cur2!=NULL)
{
if(cur1==cur2)
{
return cur1;
}
cur1=cur1->next;
cur2=cur2->next;
}
return NULL;
}
};
Leetcode142. 环形链表 II
题目链接:
思路及遇到的问题:
-
只能想到快慢指针,快指针一次走两步,慢指针一次走一步,若有环,快慢指针则必然相遇。
-
确定带环结点
-
一开始误以为相遇结点即为带环开始结点
-
推导过程
[数学公式推导]
-
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *headNode =new ListNode(0);
headNode->next=head;
ListNode *fast=headNode;
ListNode *slow=headNode;
ListNode *tmp;
while(fast->next!=NULL&&fast->next->next!=NULL&&fast->next->next!=slow->next)
{
fast=fast->next->next;
slow=slow->next;
}
tmp=slow->next;
slow=headNode;
while(tmp!=NULL)
{
slow=slow->next;
tmp=tmp->next;
if(slow==tmp)
return slow;
}
return NULL;
}
};
遇到的问题:第一个while循环可能出现空指针->于是改成:fast->next->next!=slow->next&&fast->next!=NULL&&fast->next->next!=NULL
这样会先判断fast->next->next!=slow->next
导致加上的空指针判断毫无意义
代码优化:
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
ListNode* index1 = fast;
ListNode* index2 = head;
while (index1 != index2) {
index1 = index1->next;
index2 = index2->next;
}
return index2;
}
}
return NULL;
}
};
总结
熟悉快慢指针的灵活运用
对于Leetcode142
带环结点的推导须反复揣摩