给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
1.用虚拟头节点
2.考虑交换时连接顺序
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyhead=new ListNode(0);
dummyhead->next=head;
ListNode * pre=dummyhead;
ListNode * cur=head;
while(cur!=nullptr&&cur->next!=nullptr)
{ ListNode * tmp=cur->next->next;
pre->next=cur->next;
cur->next->next=cur;
cur->next=tmp;
cur=tmp;
pre=pre->next->next;
}
return dummyhead->next;
}
};
快慢指针,快指针先走N步后,快慢指针同时走,直到快指针走到底,慢指针后一位就是需要删除的节点
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyhead=new ListNode(0);
dummyhead->next=head;
ListNode* slow=dummyhead;
ListNode* fast=dummyhead;
while(n--)
{
if(fast->next!=nullptr)
{
fast=fast->next;
}
}
while(fast->next!=nullptr)
{
slow=slow->next;
fast=fast->next;
}
//ListNode* cur=slow->next;
slow->next=slow->next->next;
// delete cur;
return dummyhead->next;
}
};
给你两个单链表的头节点
headA
和headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回null
。图示两个链表在节点
c1
开始相交:双指针
方法一:找出链表A的长度,链表B的长度,求两者差值;让短的链表先走差值步,再两者从头一起走,相遇则相交
class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { int sumA=0,sumB=0; ListNode* acur=headA; ListNode* bcur=headB; while(acur!=NULL) { acur=acur->next; sumA++; } while(bcur!=NULL) { bcur=bcur->next; sumB++; } acur=headA; bcur=headB; if(sumB>sumA) { swap(sumA,sumB); swap(acur,bcur); } int ch=sumA-sumB; while(ch--) { acur=acur->next; } while(acur!=bcur) { acur=acur->next; bcur=bcur->next; } return acur; } };
方法二:acur先走A走完了走B,bcur先走B走完了走A,最后相遇则相交
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* acur=headA;
ListNode* bcur=headB;
if(!acur||!bcur)return nullptr;
while(acur!=bcur)//要判断acur是否为空
{
if(acur==nullptr)
{ acur=headB;
bcur=bcur->next;
continue;
}
if(bcur==NULL)
{
bcur= headA;
acur=acur->next;
continue;
}
acur=acur->next;
bcur=bcur->next;
}
return acur;
}
};
给你一个链表的头节点
head
,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪
next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos
不作为参数进行传递 。仅仅是为了标识链表的实际情况。如果链表中存在环 ,则返回
true
。 否则,返回false
。
快慢指针,快指针走两步,慢指针走一步,最后再相遇
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode* fast=head;
ListNode* slow=head;
while(fast!=NULL&&fast->next!=NULL)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)return fast;
}
return fast;
}
};
给定一个链表的头节点
head
,返回链表开始入环的第一个节点。 如果链表无环,则返回null
。如果链表中有某个节点,可以通过连续跟踪
next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果pos
是-1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
1.先判断是否有环,判断后找入口
2.相遇时slow走了x+y,fast走了x+y+n(y+z),fast可能在环里面绕圈,fast=2*slow,2(x+y)=x+y+n(z+y),当n=1时,化简为x=z,此时让两个指针分别从相遇点和头节点处一起走,在环形入口处相遇
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode*fast=head;
ListNode*slow=head;
if(!head||!head->next)return NULL;
while(fast!=NULL&&fast->next!=NULL)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
{
ListNode* index1=head;
ListNode* index2=fast;
while(index1!=index2)
{
index1=index1->next;
index2=index2->next;
}
return index1;
}
}
return NULL;
}
};