C++:Leetcode-链表-24两两交换链表中的节点
链表联系题,加强虚拟头节点运用,加强节点交换后指针指向也随之改变的理解
题目
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
一、思路分析
结合画图进行理解
1、创建虚拟头节点、现节点方便后续操作
2、记录第1个节点和第3个节点,方便后续交换的操作
3、进行交换,步骤一:现节点即虚拟头节点指向2节点,此时cur->next为2节点
4、步骤二:2节点指向原来的1节点,原来1节点由temp1记录,此时cur->next->next为1节点
5、步骤三:1节点指向原来的3节点,原来3节点由temp2记录,此时cur->next->next->next为1节点的指向即3节点
6、两两交换完毕,现节点向后移动两位,完成一轮交换
7、不断循环,用while判定,当两个相邻节点都不为空时进行交换
重点理解:
1、节点进行交换后,节点的指向也随之改变,别漏了这个。
2、还有返回的是交换后的头节点,但mylist中的虚拟头结点指向没有改变,还是指向最初的1,而不是交换后的2(这个不影响leetcode通过,只是影响自己输出打印)
思路流程图如下:
二、代码
/*
Leetcode-24两两交换链表中的节点
思路:
结合画图进行理解
1、创建虚拟头节点、现节点方便后续操作
2、记录第1个节点和第3个节点,方便后续交换的操作
3、进行交换,步骤一:现节点即虚拟头节点指向2节点,此时cur->next为2节点
4、步骤二:2节点指向原来的1节点,原来1节点由temp1记录,此时cur->next->next为1节点
5、步骤三:1节点指向原来的3节点,原来3节点由temp2记录,此时cur->next->next->next为1节点的指向即3节点
6、两两交换完毕,现节点向后移动两位,完成一轮交换
7、不断循环,用while判定,当两个相邻节点都不为空时进行交换
*/
#include "iostream"
#include "vector"
#include "list"
using namespace std;
//创建节点
class ListNode
{
public:
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *l_next) : val(x), next(l_next) {}
};
//创建链表
class myLinkedList
{
public:
int listsize;
ListNode *dummyNode;
myLinkedList()
{
listsize = 0;
dummyNode = new ListNode(0);
}
ListNode *creatList(vector<int> &nums)
{
ListNode *current = new ListNode(nums[0]);
dummyNode->next = current;
for (int i = 1; i < nums.size(); i++)
{
current->next = new ListNode(nums[i]);
current = current->next;
}
listsize += nums.size();
return dummyNode->next;
}
void printList(ListNode *head)
{
ListNode *current = head;
while (current != nullptr)
{
cout << current->val << "\t";
current = current->next;
}
cout << endl;
}
};
class Solution
{
public:
ListNode *swapPairs(ListNode *head)
{
ListNode *dummyNode = new ListNode(0); //创建虚拟头节点,方便操作
dummyNode->next = head;
ListNode *cur = dummyNode; //创建现节点,进行移动操作
while (cur->next != nullptr && cur->next->next != nullptr) //当两个节点都不为空时,进行两两交换操作
{
ListNode *temp1 = cur->next; //记录第一个节点,方便后续交换操作
ListNode *temp2 = cur->next->next->next; //记录第三个节点,方便后续交换操作
//开始进行交换
//结合换图进行理解
cur->next = cur->next->next; //现节点即虚拟头节点指向2节点,此时cur->next为2节点,步骤1
cur->next->next = temp1; //2节点指向原来的1节点,原来1节点由temp1记录,此时cur->next->next为1节点,步骤2
cur->next->next->next = temp2; //1节点指向原来的3节点,原来3节点由temp2记录,此时cur->next->next->next为1节点的指向即3节点,步骤3
cur = cur->next->next; //两两交换完毕,现节点向后移动两位,完成一轮交换
}
return dummyNode->next; //返回头节点,但mylist中的虚拟头结点指向没有改变,还是指向1,而不是交换后的2
}
};
int main(int argc, const char **argv)
{
myLinkedList mylist;
vector<int> nums = {1, 2, 3, 4, 5};
mylist.creatList(nums);
mylist.printList(mylist.dummyNode->next);
Solution s1;
mylist.dummyNode->next = s1.swapPairs(mylist.dummyNode->next); //改变mylist中虚拟头节点的指向
mylist.printList(mylist.dummyNode->next);
return 0;
}
总结
链表的加强理解与加强运用。
参考代码随想录
https://www.programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html#%E6%80%9D%E8%B7%AF