代码随想录Day 链表part02
文章参考的代码随想录的网址:两两交换链表中的节点等
24. 两两交换链表中的节点
思路:(双指针法)首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。然后就要开始反转了,首先要把 cur->next 节点用tmp指针保存一下,也就是保存一下这个节点
/**
* 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* swapPairs(ListNode* head) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* cur = dummyHead;
while(cur->next != nullptr && cur->next->next != nullptr){ // 遍历的终止条件:节点数量分为奇数、偶数
ListNode* temp = cur->next;
ListNode* temp1 = cur->next->next->next;
cur->next = cur->next->next; // 交换节点的操作1
cur->next->next = temp; // 操作2
temp->next = temp1; // 操作3
cur = cur->next->next; // 移动cur的指向,指向要反转的两个节点的前一个节点(移动两个位置)
}
// return dummyHead->next;
// 若想把虚拟头结点删除掉,则用result
ListNode* result = dummyHead->next;
delete dummyHead;
return result;
}
};
19.删除链表的倒数第N个节点
/**
* 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) {}
* };
*/
// 双指针方法,快慢指针一开始同时指向dummyHead 虚拟头指针
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* fast = dummyHead;
ListNode* slow = dummyHead;
n++;
while(n-- && fast!=nullptr){ // 让快指针先移动 n+1 步
fast = fast->next;
}
while(fast != nullptr ){ // 快慢指针同时移动,直到fast指向空指针,跳出,此时slow指针指向要删除的节点的上一个节点
fast = fast->next;
slow = slow->next;
}
// 删除链表的倒数第N个节点, 并释放掉倒数第n节点的内存
ListNode * temp = slow->next;
slow->next = temp->next;
delete temp;
return dummyHead->next;
}
};
面试题 02.07. 链表相交
/**
* 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) {
ListNode* curA = headA;
ListNode* curB = headB;
int lenA = 0, lenB = 0;
while (curA != NULL) { // 求链表A的长度
lenA++;
curA = curA->next;
}
while (curB != NULL) { // 求链表B的长度
lenB++;
curB = curB->next;
}
curA = headA;
curB = headB;
// 让curA为最长链表的头,lenA为其长度
if (lenB > lenA) {
swap (lenA, lenB);
swap (curA, curB);
}
// 求长度差
int gap = lenA - lenB;
// 让curA和curB在同一起点上(末尾位置对齐)
while (gap--) {
curA = curA->next;
}
// 遍历curA 和 curB,遇到相同则直接返回
while (curA != NULL) {
if (curA == curB) {
return curA;
}
curA = curA->next;
curB = curB->next;
}
return NULL; // 无相同的指针地址(交点),则返回null
}
};
142. 环形链表
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast != NULL && fast->next != NULL){ // 遍历查找的终止条件
fast = fast->next->next;
slow = slow->next;
if(fast == slow){ //快慢指针相遇,必然有环,然后去找环形的进入点
ListNode* index1 = fast;
ListNode* index2 = head;
while(index1 != index2){ // index1 index2 相等,while循环终止;两个节点同时到达环形入口的节点
index1 = index1->next;
index2 = index2->next;
}
return index1;
}
}
return NULL;
}
};