目录
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-words-in-a-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
一.题目描述
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。
注:你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
二.题目示例
示例一:
输入:head = [1,2,3,4] 输出:[2,1,4,3]
示例二:
输入:head = [] 输出:[]
本体采用两种方法,递归和非递归方法。
三.递归方法
递归的条件是链表中至少有两个节点,如果链表中只有一个或者没有节点的话,则终止递归(直接返回head)。因为是两两交换,可以理解双数节点都变成新的头节点,而且单数节点都会成为递归的头节点,我们可以根据这个条件来写递归。第二个节点就顺理成章的成为新的头节点,设一个newHead表示新的头节点(以后的双数节点都会变成newHead,但只有第二个节点成为了新链表的真正头节点),那么原始头节点的下一个节点就变为了第三个节点,正好第三个节点为下一层递归的头节点,则head->next=swapPairs(newHead->next);然后newHead->next=head;,就可以完成所有的交换。
代码详解:
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;
}
};
四.非递归方法
在链表中两个节点交换中,则需要新定义两个节点,一个用来存放该节点的下一个节点,一个用来存放该节点的下下一个节点,因为在我们移动链表指向方向时容易找不到该节点原来所指。这时候就可以进行两节点交换,为上述该节点的下一个节点和该节点的下下一个节点交换。交换完成后我们需要移动指针的位置,因为是两两交换,指针指向该节点没移动前的下一个节点。最后还需要一个循环来搞定它,在递归中说到递归的条件是遍历到节点没有为止,那么此次循环的条件就是指针所指节点的下一个和下下一个节点存在才可。
交换两个节点的位置
设ABCD三个节点,交换B和C节点的位置,我们需要A节点的next指向C节点,然后B节点的next指向D节点,最后C节点的next指向B指针,B和C节点就交换完毕了
基本步骤:
1.定义一个空节点,指向头指针,方便遍历
2.进行遍历,定义两个节点存放指针节点的下个节点和下下个节点
3.指针节点指向下下个节点
4.指针节点的下个节点指向第四个节点
5.指针节点下下个节点指向下个节点
6.移动指针,指向原节点下下个节点
以示例一为例,画图讲解交换过程
代码详解:
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
//定义一个虚拟节点
ListNode* firstHead = new ListNode(0);
//虚拟节点指向头节点
firstHead->next = head;
//定义一个指针指向虚拟头节点
ListNode* temp = firstHead;
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;
}
return firstHead->next;
}
};
好啦,这道题就讲解完成了,以后我也会多多更新的,欢迎大家持续关注我哟!