题目:
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:

输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
提示:
链表中节点的数目在范围 [0, 100] 内
0 <= Node.val <= 100
进阶:你能在不修改链表节点值的情况下解决这个问题吗?(也就是说,仅修改节点本身。)
分析:
主要想法是用递归或迭代来解决问题。
- 递归:
使用递归来解决该题,主要就是递归的三部曲:
1.找终止条件:本题终止条件很明显,当递归到链表为空或者链表只剩一个元素的时候,没得交换了,自然就终止了。
2.找返回值:返回给上一层递归的值应该是已经交换完成后的子链表。
3.单次的过程:因为递归是重复做一样的事情,所以从宏观上考虑,只用考虑某一步是怎么完成的。我们假设待交换的俩节点分别为head和next, next 的应该接受上一级返回的子链表(参考第2步)。就相当于是一个含三个节点的链表交换前两个节点,就很简单了。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* swapPairs(struct ListNode* head){
if(head==NULL||head->next==NULL) //头指针为空或只有一个结点
return head; //递归出口
struct ListNode *newnode;
newnode=head->next;
head->next=swapPairs(newnode->next);//返回值是已经交换完的子链表
newnode->next=head;
return newnode;
}
2.迭代:
迭代的思路比较容易想到,但是要注意边界情况。这里我们设置哑结点来方便操作。
struct ListNode* swapPairs(struct ListNode* head){
struct ListNode *temp,*dummy=(struct ListNode*)malloc(sizeof(struct ListNode));
dummy->next=head;
temp=dummy;
while(temp->next!=NULL&&temp->next->next!=NULL){
struct ListNode *node1=temp->next;
struct ListNode *node2=temp->next->next;
temp->next=node1->next;
node1->next=node2->next;
node2->next=node1;
temp=node1;
}
return dummy->next;
}
本文介绍了如何使用递归和迭代两种方法解决链表中两两交换节点的问题。递归解决方案通过找到终止条件、确定返回值和处理单次过程来实现。迭代方案则利用哑结点辅助,不断交换相邻节点直至遍历结束。两种方法都展示了清晰的逻辑和边界条件处理。
1150

被折叠的 条评论
为什么被折叠?



