题目描述
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
解题思路
1. 迭代
我们要交换的一对链表分为两部分,奇数节点为一部分,偶数节点为另一部分。A 指的是这一部分交换节点中的前面的节点,B 指的是要交换节点中的后面的节点。在完成它们的交换,同时用 prevNode 记录 A 的前驱节点。
firstNode(即 A) 和 secondNode(即 B) 分别遍历偶数节点和奇数节点,即两步看作一步。
0. 迭代开始前,指定 A, B 节点
fristNode = head; (A)
secondNode = head->next; (B)
1.完成A,B两个节点的交换;
firstNode.next = secondNode.next
secondNode.next = firstNodepre->A->B->C => B->A->C
2. 将前驱节点指向B节点
pre.next = secondNodepre->B->A->C
这样完成了一对节点的更换;
3. 迭代头指针和前驱指针,进行下一对节点的更新
head = frist->next;
pre = frist;
代码
class Solution
{
public:
ListNode* swapPairs(ListNode* head)
{
/* 创建 前驱节点(哑结点,头结点)储存 第一个节点的前驱指针
*/
ListNode* dummy = new ListNode(-1);
dummy->next = head;
ListNode* pre = dummy;
while(head != NULL && head->next != NULL)
{
//要被交换的节点
ListNode* first = head;
ListNode* second = head->next;
//交换
pre->next = second;
first->next = second->next;
second->next = first;
//迭代头指针和 前驱指针,进行下一对节点的交换
pre = first;
head = first->next;
}
return dummy->next;
}
};
2.递归
递归的思路在交换节点数据方面和前面迭代类似
递归的输入是头结点,
输出是 交换过后的头结点;
这样,在交换节点是,A(原本的第一个节点,交换到后面去了)指向的应该是后面一对节点处理过后返回的头结点。
代码
class Solution
{
public:
ListNode* swapPairs(ListNode* head)
{
/*
递归
输入是 头结点
返回值为被交换后的头结点
*/
if(head == NULL || head->next == NULL)
{
return head;
}
//指定被交换的节点
ListNode* first = head;
ListNode* second = head->next;
//交换节点
//第一个节点指向后一对节点的第一个节点
first->next = swapPairs(second->next);
second->next = first;
//返回头结点,即此时的第二个节点
return second;
}
};