#请看题
解法
还是链表题,不过从一直刷的简单到中等难度了。有点难理解,不过还是把这个知识点给吃下来了。
首先我们可以看到再给出的两个example中,直接返回了其的值,这是一个小提示。我们可以直接写出一个if来返回head节点。
最简单的一部分我们已经解决了,这时候我们能够过两个test,想要真正的去完成这道题,还是要去学会其中的知识。
有两种解法,分别是递归和迭代。
先来想迭代应该怎么去解决。
迭代
在这个example中,可以看到如果一个链表只有三个节点,只会交换第一个和第二个节点,第三个节点无需交换,这意味着什么呢?
意味着如果当前节点的下下个节点如果为空的话,那么就可以不用去处理,这是一个提前结束的条件。
好,解决了其中的一个难点后,接下来是要去想应该怎么去交换节点呢?其实是很简单的,只需要定义几个指针变量指向当前的节点,下个节点和下下个节点,然后交换它们对的指向就可以了。
答案
/**
* 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) {
if(head == nullptr || head->next == nullptr){
return head;
}
ListNode dummy(0);
dummy.next = head;
ListNode *prev = &dummy;
while(prev->next && prev->next->next){
ListNode *first = prev->next;
ListNode *second = first->next;
ListNode *nextPair= second->next;
prev->next = second;
second->next = first;
first->next = nextPair;
prev = first;
}
return dummy.next;
}
};
在这里有一个图来帮助我们更好的理解。首先,这是一个有着四个节点的链表,根据前面的while循环条件,可以看出这四个节点一共会运行两次,两次后得出的结果就是答案,那么,这个答案是怎么得到的呢?
很好的问题,不过很简单。
只需要定义一个dummy变量来指向head,然后再来一个prev来指向dummy。这时候dummy.next和prev都指向了我们的头节点,也就是1
在循环中,在定义三个指针变量,来获取当前节点(prev指向的dummy.next,也就是first), 当前的下一个(second指针变量)和下下个节点(nextPair指针变量),在和它们来进行交换就好了。这里具体的过程是
首先dummy.next 和 prev都指向了1,1也是我们的first指针变量,2是second,3是nextpair。prev->next = second 这里修改了指向,运行到这里链表结构会变成 2 2 3 4, 然后second->next = first,链表变成2 2 1 4,最后first-next = nextPair,链表变为2 3 1 4,此后循环继续,直到下下个节点为空。最后的答案是 2 1 4 3
上一段内容有一点绕,但是只要拿起笔来算一算就懂了,这里唯一的难点就是逻辑太绕,很容易脑子就会发热,容量不足死机。
递归
递归这里在leetcode上会有一个超时的问题,但是这不影响代码是正确的。
/**
* 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) {
if (head == nullptr || head->next == nullptr) {
return head;
}
ListNode* first = head;
ListNode* second = head->next;
first->next = swapPairs(head->next);
second->next = first;
return second;
}
};