题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4] 输出:[2,1,4,3]
示例 2:
输入:head = [] 输出:[]
示例 3:
输入:head = [1] 输出:[1]
1.我的思路:一开始没搞懂要干嘛,后来才发现是每两个单位交换结点位置,我还在想要是奇数个该怎么办,没思路,看题解
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return head;
}
ListNode* newHead = head->next;
head->next = swapPairs(newHead->next);
newHead->next = head;
return newHead;
}
};
2.这是题解的第一个方法,递归遍历每两个结点,先创造一个新头结点,即newHead,这个结点便是原链表的第二个结点,故把head->next的值赋给它,接着开始操作head后面的部分,用递归传入参数newHead->next,即原链表的第三位head->next->next,recursion完毕后把head的值给newHead->next,最终返回交换好后的链表。(注意这里if语句的比较不能去掉后面head->next的判断,如果去掉,当链表只有一个结点的时候便会传一个空指针进swapPairs,引起报错)
我看了遍题解自己写的时候就这么报错了:D
3.迭代
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* temp = dummyHead;
while (temp->next != nullptr && temp->next->next != nullptr) {
ListNode* node1 = temp->next;
ListNode* node2 = temp->next->next;
temp->next = node2;
node1->next = node2->next;
node2->next = node1;
temp = node1;
}
ListNode* ans = dummyHead->next;
delete dummyHead;
return ans;
}
};
运用链表问题里经典的哑巴结点,temp把链表分为两个两个,while的判断条件里是判断两两分组后没有空指针和单独的结点,循环里将两两分组后的两个结点交换
交换之前的节点关系是 temp -> node1 -> node2,交换之后的节点关系要变成 temp -> node2 -> node1,因此需要进行如下操作。
temp.next = node2
node1.next = node2.next
node2.next = node1
完成上述操作之后,节点关系即变成 temp -> node2 -> node1。再令 temp = node1,对链表中的其余节点进行两两交换,直到全部节点都被两两交换。
最终返回哑巴节点的next,便game over