10.23链表练习
2.4反转链表
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* pre = nullptr;创建一个空的头节点
ListNode* cur = head;
ListNode* temp;
while(cur){
temp = cur->next;//保存后方链表
cur->next=pre;//将原来cur的next指针反向指向它的前驱结点pre
pre=cur;//pre和cur同步向后方移动
cur=temp;
}
return pre;//返回的是pre,此时cur作为循环出口为空
}
};
2.5两两交换链表结点

class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* p=dummyHead;
while(p->next != nullptr && p->next->next != nullptr){
ListNode* temp1 = p->next;//保存头结点后的第一个结点
ListNode* temp2 = p->next->next->next;//保存下一组准备交换的元素首位
p->next = temp1->next;
temp1->next->next = temp1;
temp1->next = temp2;
p=p->next->next;
}
return dummyHead->next;
}
};
2.6删除链表的倒数第k个结点
快指针先行移动k个位置。然后快慢指针同步移动
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* p = dummyHead;
ListNode* q = dummyHead;//快慢指针
while(n--)
p=p->next;
p=p->next;//这里容易丢失。如果没有实际上q最终指向的是待删除元素本身而不是前驱
while(p){
p=p->next;
q=q->next;
}
q->next = q->next->next;
return dummyHead->next;
}
};
2.7链表相交
先找出两个;链表长度之差。然后同步链表向后方移动。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int count1=0,count2=0,dist;//dist是差额
ListNode* longlist;
ListNode* shortlist;
ListNode* p=headA;
ListNode* q=headB;
while(p){
count1++;
p=p->next;
}
while(q){
count2++;
q=q->next;
}
if(count1>count2){
longlist = headA;
shortlist = headB;
dist = count1-count2;
}
else{
longlist = headB;
shortlist = headA;
dist = count2-count1;
}
while(dist--)
longlist = longlist->next;
while(longlist){
if(longlist == shortlist)
return longlist;
longlist = longlist->next;//这两个部分不能忘
shortlist = shortlist->next;
}
return 0;
}
};
2.8环形链表
fast指针每次移动两步,slow指针每次移动一步。如果存在环形则两指针一定可以相遇。
x是头结点到环形入口的长度;y是环形入口到相遇点的长度;z是相遇点到环形入口的长度。
推导过程: fast位移距离:x+y+n(y+z)
slow位移距离:x+y
(x+y)2 = x+y+n(y+z) => x+y = n(y+z) => x = (n-1)y+nz => x = (n-1)*(y+z)+z
对于n=1时,公式是x = z
相当于,如果两指针分别从头结点和相遇结点出发,都是一个步伐长度的移动。那么这两者的位移距离是相同的。此时这个位移的终点就是我们的环形入口结点

class Solution {
public:
ListNode *detectCycle(ListNode *head) {
int count=0;
ListNode* fast;
ListNode* slow;
fast = head;
slow = head;
while(fast&&fast->next){
fast = fast->next->next;
slow = slow->next;
if(fast == slow){
ListNode* index1 = fast;
ListNode* index2 = head;
while(index1!=index2){
index1 = index1->next;
index2 = index2->next;
}
return index1;
}
}
return 0;
}
};

浙公网安备 33010602011771号