代码随想录算法训练营第四天 24. 两两交换链表中的节点
一、两两交换链表中的节点
花了点时间画图盘了一下逻辑,然后才做了出来。但是操作相对复杂一点。
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummynode = new ListNode(0);
dummynode->next = head;
ListNode* cur = dummynode->next;
ListNode* temp;
if(cur == NULL || cur->next == NULL){
return head;
}
head = cur->next;
while(cur != NULL && cur->next != NULL){
temp = cur;
cur = cur->next;
dummynode->next->next = cur;
temp->next = cur->next;
cur->next = temp;
cur = temp->next;
dummynode->next = temp;
}
delete dummynode;
return head;
}
};
还是Carl哥的方法通顺好理解,且后面二刷的时候容易记住。
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点
dummyHead->next = head; // 将虚拟头结点指向head,这样方面后面做删除操作
ListNode* cur = dummyHead;
while(cur->next != nullptr && cur->next->next != nullptr) {
ListNode* tmp = cur->next; // 记录临时节点
ListNode* tmp1 = cur->next->next->next; // 记录临时节点
cur->next = cur->next->next; // 步骤一
cur->next->next = tmp; // 步骤二
cur->next->next->next = tmp1; // 步骤三
cur = cur->next->next; // cur移动两位,准备下一轮交换
}
return dummyHead->next;
}
};
二、删除链表的倒数第N个节点
题目链接
暴力解法:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
int size = 0;
ListNode* dummnode = new ListNode(0);
dummnode->next = head;
ListNode* cur = dummnode;
while(cur->next != NULL){
cur = cur->next;
size++;
}
cur = dummnode;
for(int i =0; i<(size-n);i++){
cur = cur->next;
}
ListNode* temp = cur->next;
cur->next = cur->next->next;
delete temp;
head = dummnode->next;
delete dummnode;
return head;
}
};
滑动窗口的思想:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummynode = new ListNode(0);
dummynode->next = head;
ListNode* fast_cur = dummynode;
ListNode* slow_cur = dummynode;
while(fast_cur->next != NULL){
if(n){
fast_cur = fast_cur->next;
n--;
}
else{
fast_cur = fast_cur->next;
slow_cur = slow_cur->next;
}
}
ListNode* temp = slow_cur->next;
slow_cur->next = slow_cur->next->next;
delete temp;
return dummynode->next;
}
};
三、160.链表相交
题目链接
一刷思路:算长度的差值,然后对齐
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* curA = headA;
ListNode* curB = headB;
int sizeA = 0;
int sizeB = 0;
while(curA != NULL){
curA = curA->next;
sizeA++;
}
while(curB != NULL){
curB = curB->next;
sizeB++;
}
curA = headA;
curB = headB;
int difference = sizeA-sizeB;
if(difference > 0){
while(difference--){
curA = curA->next;
}
}
else if(difference < 0){
while(difference++){
curB = curB->next;
}
}
while(curA != curB){
curA = curA->next;
curB = curB->next;
}
return curA;
}
};
群里看到的更简洁的写法,其实思路是一样的一个是算差值,一个是相加。
a+c+b = b+c+a;
设交集链表长c,链表1除交集的长度为a,链表2除交集的长度为b,有
- a + c + b = b + c + a
- 若无交集,则a + b = b + a
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* curA = headA;
ListNode* curB = headB;
while(curA != curB){
curA = curA == NULL? headB : curA->next;
curB = curB == NULL? headA : curB->next;
}
return curA;
}
};
四、 142.环形链表II
题目链接
这题一点思路也没有,直接看的carl的题解思路,代码实现不难。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fastcur = head;
ListNode* slowcur = head;
while(fastcur != NULL && fastcur->next != NULL){
fastcur = fastcur->next->next;
slowcur = slowcur->next;
if(slowcur == fastcur){
slowcur = head;
while(slowcur != fastcur){
slowcur = slowcur->next;
fastcur = fastcur->next;
}
return slowcur;
}
}
return NULL;
}
};
五、总结
整体来说对链表的理解更深了一步,除了最后一题,其他的一刷能能做出来。
本文介绍了四种链表相关的算法问题:两两交换链表中的节点,删除链表的倒数第N个节点,寻找两个链表的交点,以及检测环形链表。文中对比了不同解法,包括使用虚拟头节点、滑动窗口等技巧,并提供了详细的代码实现。这些方法加深了对链表操作的理解。
419

被折叠的 条评论
为什么被折叠?



